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

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

Автор: PSW

Введение
Кратко о динамической памяти
Структура 3DS файла
Заключение

Введение

С начала уточним, что эта статейка предназначена для тех кто еще не имеет опыта работы с 3DS файлами. Так же я предполагаю, что Вы знаете основы языка С++. В частности важно уметь выделять память из кучи, т. е. использовать динамическую память. Но и незнание этого не проблема - будут краткие пояснения.

Сформулируем задачу.

Мы хотим импортировать в нашу программу модель объекта созданного в 3DStudioMAX. Несмотря на то, что 3DS файл хранит в себе уйму информации: про настройку сцены, про все объекты сцены, про материалы и анимацию. Нас будет интересовать только сама модель объекта. Не думаю, что на первом этапе Вы захотите писать несколько экрано-метров кода, да и зачем.

Объект состоит из треугольников, которые образуются тройками вершин (точек трехмерного пространства (x, y, z)). Кроме того, каждой вершине объекта соответствует точка текстуры (горизонтальная координата u и вертикальная v). Также имеем для каждой вершины вектор нормали, он же - точка трехмерного пространства. Нормали необходимы при использовании освещения, и считаются для модели после импортирования отдельно (в 3DS файле их вроде бы нет, да и не нужны они там).

Сначала рассмотрим базовые понятия, потом структуру файла 3DS, ну а под конец и реализацию самого импорта объекта.

Типы и переменные:

class TPointR3 //Точка трехмерного пространства R3, т. е. (x, y, z)
{
public:
float r0;
float r1;
float r2;
private:
      : (набор функций)
public:
      : (набор функций и перегрузка операторов) 		
};

Если Вас смущает класс, то воспринимайте точку просто как структуру (что в принципе то же самое):

struct TPointR3
{
float r0;
float r1;
float r2;
};

Аналогично определяются TPointR2, TPointR4.

Для того чтобы определить треугольник нам необходимо выбрать из массива вершин три любые. Для хранения индексов этих вершин мы и будем использовать следующую структуру:

struct TFace
{
unsigned short v0;
unsigned short v1;
unsigned short v2;
};
nVertexs - количество вершин;
nTriangles (возможно Вам больше понравиться nFace, мне - нет) - количество треугольников;
Vertexs (он же возможно Vertices) - массив вершин;
Triangles - массив треугольников (элемент - тройка индексов);
TexCoords - массив текстурных координат;
Normals - массив векторов нормалей в вершинах (не обязательно);

То есть на C++ это будет выглядеть примерно так:

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

class T3DMesh//Класс хранящий в себе каркасную сетку - наш объект
{
private:
    string Name;//Имя сетки
    unsigned short countUse;//Количество ссылок на сетку
    string File;//Файл сетки
    bool isTranslate;//Флаги преобразований
    bool isRotate;
    bool isScale;
    TPointR3 Center;//Координаты сетки в локальной системе
    TPointR3 Coner;//Наклон сетки в локальной системе
    TPointR3 Scale;//Масштабирование  сетки
    unsigned short nVertexs;//Количество вершин
    TPointR3 *Vertexs;//Указатель на массив вершин
    unsigned short nNormals;//Количество векторов нормалей
    TPointR3 *Normals;//Указатель на массив векторов нормалей
    unsigned short nTriangles;//Количество треугольников
    struct TFace3DS{
        unsigned short v0;
        unsigned short v1;
        unsigned short v2;
        //unsigned short flags;
    } *Triangles;//Указатель на массив треугольников
    TPointR2 *TexCoords;//Указатель на массив текстурных координат
    string TexName;//Имя текстуры
    string TexFile;//Имя файла текстуры
    unsigned int texIndex;//Индекс текстуры

private:
    unsigned int FindChunk(ifstream& ifs,unsigned short id,bool isParent=true);
    bool LoadMeshFrom3DS(string fname);

public:
    //...(много чего еще, но нам не важно; 
    //    доступ к реализации класса только через функции)
};

Если по минимуму (как Вам наверное будет понятнее), то имеем:

    unsigned short nVertexs;//Количество вершин
    TPointR3 *Vertexs;//Указатель на массив вершин
    TPointR3 *Normals;//Указатель на массив векторов нормалей
    unsigned short nTriangles;//Количество треугольников
    TFace3DS *Triangles;//Указатель на массив треугольников
    TPointR2 *TexCoords;//Указатель на массив текстурных координат

И две функции:

    //Функция находящая нужный блок в файле 3DS
    unsigned int FindChunk(ifstream& ifs,unsigned short id,bool isParent=true);
    //Функция именно и читающая каркасную сетку используя FindChunk()
    bool LoadMeshFrom3DS(string fname);

Если что-нибудь сейчас непонятно, то дальше все должно разъясниться.

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

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

8 мая 2003

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