Войти
ПрограммированиеСтатьиГрафика

Формат 3DS: Первый шаг. (3 стр)

Структура 3DS файла

Следует заметить, что в Сети есть достаточно "шифровок" (многое там неизвестно, но более чем достаточно для полного импорта сцены) данного формата на английском языке, да и на руссом встречаются. Нормальный поисковик выдаст Вам достаточно ссылок. Качайте все, а там разберетесь. Эта статья дает мизерную долю информации по сравнению со всей. Например, воспользуйтесь ссылкой: http://www.wotsit.org/.

Файл состоит из блоков (chunk), которые в свою очередь могут содержать данные или другие блоки (они уже являются как бы подблоками).

Структура блока такая:

unsigned short chunk_id;//Идентификатор , определяет тип блока (2 байта)
unsigned int chunk_len;//Длинна блока в байтах (4 байта)
//Содержание блока (данные или подблоки)

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

Так выглядит *.3DS файл (если очень коротко).

Самая основа:

                  MAIN3DS  (0x4D4D)
                  |
                  +--EDIT3DS  (0x3D3D)
                  |    |
                  |    ...(последовательность разных блоков)
                  |
                  +--KEYF3DS (0xB000)
                       |
                       ...(последовательность разных блоков)

Более полно:

                  MAIN3DS     (0x4D4D)
                  |
                  +--EDIT3DS     (0x3D3D)
                  |    |
                  |    ...(последовательность разных блоков)
                  |    |
                  |    +--EDIT_OBJECT     (0x4000)
                  |    |    |
                  |    |    +--OBJ_TRIMESH     (0x4100)
                  |    |    |    |
                  |    |    |    +--TRI_VERTEXLIST     (0x4110)
                  |    |    |    +--TRI_VERTEXOPTIONS     (0x4111)
                  |    |    |    +--TRI_MAPPINGCOORS     (0x4140)
                  |    |    |    +--TRI_MAPPINGSTANDARD     (0x4170)
                  |    |    |    +--TRI_FACELIST     (0x4120)
                  |    |    |    |    |
                  |    |    |    |    +--TRI_SMOOTH      (0x4150)
                  |    |    |    |    +--TRI_MATERIAL     (0x4130)
                  |    |    |    |
                  |    |    |    +--TRI_LOCAL     (0x4160)
                  |    |    |    +--TRI_VISIBLE     (0x4165)
                  |    |    |
                  |    |    ...(последовательность разных блоков)
                  |    |
                  |    ...(последовательность разных блоков)
                  |
                  +--KEYF3DS     (0xB000)
                       |
                       ...(последовательность разных блоков)

Первые два байта определяют тип файла MAIN3DS(0x4D4D). Дальше идут два блока - блок редактора и анимации. Нас будет интересовать только первый, т. е. EDIT3DS(0x3D3D). В нем нам нужно будет найти блок объекта (объектом может быть каркасная сетка, источник света и камера) EDIT_OBJECT(0x4000). В нем в свою очередь найти сетку треугольников OBJ_TRIMESH(0x4100) и наконец-то считать данные.

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

В EDIT_OBJECT(0x4000) после chunk_id и chunk_len идет ASCIIZ строка с завершающим нулевым символом '\0'. Это имя объекта. А потом уже идут подблоки. Не забывайте это!

Рассмотрим структуру интересующего нас блока OBJ_TRIMESH(0x4100):

TRI_VERTEXLIST (0x4110)
	unsigned short nVertexs;//Число вершин
	vector Vertexs[nVertexs];//Координаты каждой вершины; vector=TPointR3= три float;

TRI_VERTEXOPTIONS (0x4111)
	//Нас не интересует

TRI_FACELIST (0x4120)
unsigned short nTriangles;//Число треугольников
struct {
unsigned short v0;//Индекс первой вершины
unsigned short v1;//Индекс второй вершины
unsigned short v2;//Индекс третьей вершины
unsigned short flags;//Флаги грани, которые мы смело будем игнорировать
} Triangles[nTriangles];//Список граней

TRI_MATERIAL (0x4130)
	char[] Name;//Название материала - строка ASCIIZ
	unsigned short num;//Число граней использующих этот материал
	unsigned short face_mat[num];//Список индексов граней

TRI_MAPPINGCOORS (0x4140)
	unsigned short nTexCoords;//Количество текстурных координат = количеству вершин
	struct {
float u;//Текстурная координата по горизонтали
float v;// Текстурная координата по вертикали
	} TexCoords[nTexCoords];//Список текстурных координат

TRI_SMOOTH (0x4150)
	//Нас не интересует, но
	unsigned int smooth[nTriangles];//Бит на n-ом месте указывает на вхождение грани 
//в n-ую группу сглаживания (всего их понятно 32, столько сколько бит в целом без
//знака);

TRI_LOCAL (0x4160)
	float[12];//Сначала по рядках записана матрица поворота rot[3][3], 
//а потом вектор переноса	(x, y, z). Всего 12 чисел с плавающей запятой

TRI_VISIBLE (0x4165)
	//Нас не интересует

TRI_MAPPINGSTANDARD (0x4170)
	//Нас не интересует

Замечания:

Следует заметить, что в координатах вершин y и z поменяны местами. Это касается и блока перевода объекта в локальную систему координат TRI_LOCAL(0x4160). Здесь нужно быть особо внимательным.

Также важно знать, что некоторые блоки могут и отсутствовать. Так, например блок текстурных координат и блок материала объекта будут присутствовать только в случае применения к объекту материала при моделировании.

Если просто считать наш чайник, не применив к нему преобразований в локальную систему координат, то он будет выглядеть как на Рис. 2. Но если перейти в локальную систему, то центр его будет находиться ровно в точке (0.0, 0.0, 0.0) и чайник не будет наклонен ни как.

Мы говорили о массиве нормалей, который необходим для правильного освещения объекта. Так вот считать их придется Вам самим. Это очень просто реализуется, нужно только знать, что такое векторное произведение и еще кое-что.

Также следует помнить, что если Вы экспортируете не один объект, а больше, то Вам самим придется корректировать код. Т. к. возникнет необходимость сначала найти блок первого объекта, затем второго и т. д. Если этого не сделать, то Вы увидите только первый попавшийся объект.

Теперь можно перейти и к самому процессу считывания.

Я надеюсь, что мой стиль написание кода без лишних пробелов Вас не очень запутает.

Страницы: 1 2 3 4 Следующая »

#3DS, #игровой объект, #импорт, #модель, #экспорт

8 мая 2003

Комментарии [65]