Графический дизайн, арт игры, концепт, персонажи, текстуры, анимации, модели
GameDev.ru / Графический Дизайн / Форум / 3ds формат... кто стакивался, help !

3ds формат... кто стакивался, help !

m21448Постоялецwww26 дек. 200921:20#0
Здрасти !

Всех с наступающим Новым годом !

вобщемто вопрос следующий... чесно говоря для тех кто сталкивался с импортом из формата 3ds:


Нарисовал куб в 3ds Max-e и:

делаю так читаю побайтно файл ... и проверяю на нахождения чанков:

case MAIN3DS: главный
case VERTION: версия файла (вычитал на форумах что она оказзыца 6 байтом идет после главного)
case EDIT3DS: -итд
case EDIT_OBJECT: -итд
case OBJ_TRIMESH: -итд
case TRI_VERTEXLIST:

//Считаем вершины предварительно выделив память
        fread(&nVertexs,sizeof (unsigned short),1,in);
        cout<<"TRI_VERTEXLIST find = "<<nVertexs<<"\n";
        //Выделим память
        //Если уже выделяли уничтожим и выделим снова
        if(Vertexs) delete[] Vertexs;
        if(TexCoords) delete[] TexCoords;
        if(Triangles) delete[] Triangles;
        Vertexs=new TPointR3[nVertexs];
        //Считаем
        for(int i=0;i<nVertexs;i++)
        {
          fread(&Vertexs[i].r0,4,1,in);
          fread(&Vertexs[i].r2,4,1,in);//y и z поменяны местами
          fread(&Vertexs[i].r1,4,1,in);
        }
      break;

НО !!!! Вершин получаецца 26 !!! УДИВИТЕЛЬНО !!! КУБ ТО 12 Максимум ?? что за ? Кто знает помогите пожалуйста ...


Если надо то весь код:

#include "iostream"
#include "string.h"
#include "fstream"

typedef unsigned short word;
#define Dword unsigned long

  #define Dword unsigned long
  //Переменные и константы
  #define VERTION 0x0002
  #define MAIN3DS 0x4D4D  //Идентификатор *.3DS файла
    #define EDIT3DS 0x3D3D  //Блок редактора (this is the start of the editor config)
    #define EDIT_OBJECT 0x4000  //Объект (сетка, источник света, камера)
    //------ sub defines of EDIT_OBJECT
    #define OBJ_TRIMESH 0x4100
    //------ sub defines of OBJ_TRIMESH
    #define TRI_VERTEXLIST 0x4110
    #define TRI_VERTEXOPTIONS 0x4111
    #define TRI_MAPPINGCOORS 0x4140
    #define TRI_MAPPINGSTANDARD 0x4170
    #define TRI_FACELIST 0x4120
    #define TRI_SMOOTH 0x4150
    #define TRI_MATERIAL 0x4130
    #define TRI_LOCAL 0x4160
    #define TRI_VISIBLE 0x4165

struct TPointR3
  {
  float r0;
  float r1;
  float r2;
  };
struct TPointR2
  {
  float r0;
  float r1;
  };  
struct TPointR4
  {
  float r0;
  float r1;
  float r2;
  float r3;
  };

  unsigned short nTriangles;//Количество треугольников
    unsigned short nVertexs;//Количество вершин
  unsigned short temp;//Спамилка ненужое
    TPointR3 *Vertexs;//Указатель на массив вершин
      struct TFace3DS{
        unsigned short v0;
        unsigned short v1;
        unsigned short v2;
        //unsigned short flags;
    } *Triangles;//Указатель на массив треугольников
    TPointR2 *TexCoords;//Указатель на массив текстурных координат

  unsigned long FindChunk (FILE *in, unsigned short id, Dword endfile,Dword pos,
              bool isParent=false);

using namespace std; 

int main() 
{
  //------------------------------------------------------------
  //Объявления переменных
  Dword end,pos=0,lpos=0, len, tempos;
  word chunk,tw;
  char tc;
  //------------------------------------------------------------

  FILE *in=fopen("box.3DS","rb");
  if(in==NULL){cout<<"3ds::can't load";}

  fseek(in, 0, SEEK_END);
    end = ftell(in);
    fseek(in, 0, SEEK_SET);
  while (pos<end)
  {
    fread(&chunk,1,2,in);
    fread(&len,1,4,in);
    
    switch(chunk)
    {
    case MAIN3DS:
      {
      cout<<"MAIN3DS find \n";
      break;
      }
    case VERTION:
      {
      fseek(in,16,0);
      pos=ftell(in);
      cout<<"VERTION find \n";
      break;
      }
    case EDIT3DS:
      {
      cout<<"EDIT3DS find \n";
      break;
      }
    case EDIT_OBJECT:
      {
      unsigned char ch;
      int i=0;
      do
        {
          fread (&ch, 1, 1, in);
          i++;
        }while(ch != '\0' && i<20);
        cout<<"EDIT_OBJECT find \n";
        break;
      }
    case OBJ_TRIMESH:
      {
      cout<<"OBJ_TRIMESH find \n";
      break;
      }
    case TRI_VERTEXLIST:
      {
      //Считаем вершины предварительно выделив память
        fread(&nVertexs,sizeof (unsigned short),1,in);
        cout<<"TRI_VERTEXLIST find = "<<nVertexs<<"\n";
        //Выделим память
        //Если уже выделяли уничтожим и выделим снова
        if(Vertexs) delete[] Vertexs;
        if(TexCoords) delete[] TexCoords;
        if(Triangles) delete[] Triangles;
        Vertexs=new TPointR3[nVertexs];
        //Считаем
        for(int i=0;i<nVertexs;i++)
        {
          fread(&Vertexs[i].r0,4,1,in);
          fread(&Vertexs[i].r2,4,1,in);//y и z поменяны местами
          fread(&Vertexs[i].r1,4,1,in);
        }
      break;
      }
      
    default:
      {
      fseek(in,len-6,1);
      pos=ftell(in);
      }
    }
  }

altkПостоялецwww26 дек. 200921:41#1
По-моему у вас неверно спрограммировано. Что-то мне подсказывает, что вы неправильно читаете chunk-и. Может я плохо смотрел, но не нашёл в коде такой вещи: считывание из чанка лишней информации.
m21448Постоялецwww26 дек. 200922:19#2
Как нет? while в самом начале читает все подряд а switch отсеевает ...

если есть возможноть определить "лишние" эт как  ?

я счс просмотрел что он мне выдал ... и что интересно: это текстурные координаты 26 штук по 3 штуки (х,у,z)

и ещё интересней данные вначае как положено поочереди описывают каждую вершину ... а после 8 вершины (последней)
начинаеться повтор и помоему хаотичный ... вот эт прикол ..

я утверждаю что это вершины так как я сравнил с 3ds max-oм там те же данные вершин


попробывал считать 27 координат зависает ! цикл который читает файл ...

fzr125Постоялецwww26 дек. 200923:02#3
altk
> считывание из чанка лишней информации
default:
      {
      fseek(in,len-6,1);
      pos=ftell(in);
      }
вот же ж оно ж )


Да ничего странного. У самого простого куба 8 вершин... Это основа логики... А дальше идет не хаос... А именно еще 16 вершин... Да они будут повторятся, но текстурные координаты не будут... Это все разные вершины.

Где-то далее будут индексы... И по этим индексам и этим 24 вершинам (иногда и 26 - это смотря как тектсурировал) , можно грузить текстурированый куб...

Поищи на этом сайте, тут куча тем про этот формат...

m21448Постоялецwww27 дек. 200912:40#4
мгм .... вобщем счс ещё раз попробую выгрузить индексы ... т.е. TRI_FACELIST 0x4120 !

в предыдущей версии загрузчика он мне выдал размер чанка с индексами АЖ 16746 примерно ...

fzr125Постоялецwww27 дек. 200913:06#5
m21448
> размер чанка с индексами АЖ 16746 примерно

ну смотря что за модель... Но часто такое если чанк считан не правильно, а со смещением на пару байт...
Я когда писал парсер, я делал так:
1) считываем первые "магические" чанки с версиями не в цикле
2) далее каркас цикла - нашли чанк считали 6 байт (или сколько там), пропустили... - это для того чтобы тупо пролистать весь файл
3) далее в конце программы ставил строчку типа cin<<"OK!"; - и если я ее не видел при компиляции значит что произошло зацикливание или сбой
4) В теле цикла начинал дописывать по чанку - если нашли чанк - вывести его номер на экран - и что это такое тоже

Так добавлял эти самые чанки, пока не выводились все (или большинство)... Т.к. в 3дс есть такие чанки что длина его равна 16 флоатам, но в нем есть еще вложеный чанк с 4 флоатами, читать приходится все чанки...

Жаль что старый полностью рабочей ридер я выбросил, но вот мои остатки (с него я и начинал): 3DS

И вот какими доками и спеками я пользовался :
http://www.spacesimulator.net/tut4_3dsloader.html  - немного и то что есть даже с переводом
http://www.the-labs.com/Blender/3DS-details.html - наиболее полный спек что я видел
http://www.the-labs.com/Blender/3dsspec.html - от туда же

ну и это если поможет 3ds_format

Далее методом проб и ошибок.

Успехов!

m21448Постоялецwww27 дек. 200918:07#6
fzr125

спасиб .. однако все ссылки на статьи я прочел.

Вот что не могу понять:

Что бы прочитать чанк TRI_FACEL1 (0x4120)

мне надо прочитать MAIN3DS, EDIT3DS, EDIT_OBJECT, OBJ_TRIMESH,TRI_VERTEXL,TRI_VERTEXOPTIONS,TRI_MAPPINGCOORS ,TRI_MAPPINGSTANDARD И ТОЛЬКО ПОТОМ TRI_FACEL1 !
Именно прочитать эти чанки, потом прочитать все данные, и только потом TRI_FACEL1 ??!!!

  MAIN3DS  (0x4D4D)
                  |
                  +--EDIT3DS  (0x3D3D)
                  | 
                  +--EDIT_OBJECT  (0x4000)
                  |  |  |
                  |  |  +--OBJ_TRIMESH  (0x4100)     
                  |  |  |  |
                  |  |  |  +--TRI_VERTEXL          (0x4110)
                  |  |  |  +--TRI_VERTEXOPTIONS    (0x4111)
                  |  |  |  +--TRI_MAPPINGCOORS    (0x4140)
                  |  |  |  +--TRI_MAPPINGSTANDARD  (0x4170)
                  |  |  |  +--TRI_FACEL1          (0x4120)

fzr125Постоялецwww28 дек. 200916:57#7
ей богу, не помню... Но судя по картинке то да... в моем примере я не пропускал ничего, все что левое считывал в переменную flud... вообщето надо подробнее в спеках смотреть, что в себе содержит блок OBJ_TRIMESH  , и как в нем данные идут... Ну методом проб и ошибок не трудно... Просто бывает что неправильное считывание хоть одного чанка, приводит к тому что считывая по 2 байта можно наткнутся на скажем вот такие - 0x4170 - и парсер их распознает - а это не чанк, а просто данные совпали... И тогда креш... Но надо делать постепенно, аккуратно, и тогда все выйдет... Я бы дал тебе свой парсер, но я его удалил, т.к. очень злой был на *.3ds - файлы... Дерзайте и все выйдет!!! С Новым Годом кстати )))
m21448Постоялецwww29 дек. 200918:45#8
спасиб ! буду методом народного тыка !

но тема не закрыта ... всё так же жду помощи, мудрых идей, от мудрых людей ! =)

altkПостоялецwww30 дек. 20097:01#9
Вот здесь очень хорошие рабочие исходники. Проверял сам. Единственное, что надо доделать - добавить считывание TR_MATRIX и её использование.
http://wingman.org.ru/opengl/3ds-loader-animation

/ Форум / Графический Дизайн / Моделирование

Тема в архиве.

2001—2018 © GameDev.ru — Разработка игр