Структура 3DS файла
Следует заметить, что в Сети есть достаточно "шифровок" (многое там неизвестно, но более чем достаточно для полного импорта сцены) данного формата на английском языке, да и на руссом встречаются. Нормальный поисковик выдаст Вам достаточно ссылок. Качайте все, а там разберетесь. Эта статья дает мизерную долю информации по сравнению со всей. Например, воспользуйтесь ссылкой: http://www.wotsit.org/.
Файл состоит из блоков (chunk), которые в свою очередь могут содержать данные или другие блоки (они уже являются как бы подблоками).
Структура блока такая:
C++ Копировать
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):
C++ Копировать
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 Следующая страница