Войти
ПрограммированиеФорумОбщее

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

Страницы: 1 2 3 4 5 Следующая »
#30
19:17, 8 фев. 2009

#include <stdio.h>
#include <stdlib.h>

char chStr;
strcpy(chStr, "");


Прошло более 10 месяцев
#31
20:20, 29 дек. 2009

всё равно нифига не понятно !

Аctor пишет ! шестым идет версия а 16 Edit ... так блин что после 6-ого ? 4 байта есть или нет ? и ещё если дальше читать по 6 байт (2 на id чанка 4 на длинну) то на 16 байт ты никак друг не попадешь !

#32
19:58, 2 янв. 2010

Не знаю, что-то мне эти все поделки не очень нравятся. Эти бесконечные свичи и ифы.
Думаю, нужно потихоньку отходить от сищного стиля программирования.
На мой взгляд программа для загрузки 3ds (или другого формата) должна выглядеть примерно так:

- есть основной класс c3dsLoader, который является потомком Chunk<eMain_chunk>
- есть несколько иерархий чанков, в одной из которых и описан Chunk<eMain_chunk> как специализация Chunk

Эти иерархии не сложны, хоть и громозки, в частности одна из них выглядит примерно так

struct HierarchySubChunksForAllMaps 
{
  //Ýòî ïåðå÷èñëåíèå âêëþ÷àåò â ñåáÿ âñå ñïåöèàëèçàöèè èåðàðõèè êëàññîâ, 
  //äîëæíî õðàíèòñÿ îòñîðòèðîâàííûì è çàêàí÷èâàòüñÿ ÷èñëîì ýëåìåíòîâ ïåðå÷èñëåíèÿ enEndNumber
  enum enMemberList
  {
    eBlur_percent = 0xA353,        // Blur percent/
    eMapping_filename = 0xA300,      // Mapping filename/
    eMapping_parameters = 0xA351,    // Mapping parameters/
    eRGB_Luma_Alpha_tint_1 = 0xA360,  // RGB Luma/Alpha tint 1
    eRGB_Luma_Alpha_tint_2 = 0xA362,  // RGB Luma/Alpha tint 2
    eRGB_tint_B = 0xA368,        // RGB tint B/
    eRGB_tint_G = 0xA366,        // RGB tint G/
    eRGB_tint_R = 0xA364,        // RGB tint R/
    eRotation_angle = 0xA35C,      // Rotation angle/
    eU_offset = 0xA358,          // U offset/
    eU_scale = 0xA356,          // U scale/
    eV_offset = 0xA35A,          // V offset/
    eV_scale = 0xA354,          // V scale/
    enEndNumber = 12
  };

  class Parent 
  {
  public:
    Parent()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo()=0;
    static const enMemberList  id() { return enEndNumber; }
    virtual void operator>>(ofstream &outMotorFile) = 0;  
    virtual void operator<<(ifstream &inMotorFile) = 0;
  };
  
  template <enMemberList enAn> 
  class Chunk : virtual public Parent 
  {
    public:
    Chunk()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return enAn; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eBlur_percent> : virtual public Parent 
  {
  public:
    Chunk<eBlur_percent>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eBlur_percent; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eMapping_filename> : virtual public Parent 
  {
  public:
    Chunk<eMapping_filename>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eMapping_filename; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eMapping_parameters> : virtual public Parent 
  {
  public:
    Chunk<eMapping_parameters>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eMapping_parameters; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eRGB_Luma_Alpha_tint_1> : virtual public Parent 
  {
  public:
    Chunk<eRGB_Luma_Alpha_tint_1>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRGB_Luma_Alpha_tint_1; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eRGB_Luma_Alpha_tint_2> : virtual public Parent 
  {
  public:
    Chunk<eRGB_Luma_Alpha_tint_2>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRGB_Luma_Alpha_tint_2; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eRGB_tint_B> : virtual public Parent 
  {
  public:
    Chunk<eRGB_tint_B>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRGB_tint_B; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eRGB_tint_G> : virtual public Parent 
  {
  public:
    Chunk<eRGB_tint_G>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRGB_tint_G; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eRGB_tint_R> : virtual public Parent 
  {
  public:
    Chunk<eRGB_tint_R>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRGB_tint_R; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eRotation_angle> : virtual public Parent 
  {
  public:
    Chunk<eRotation_angle>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eRotation_angle; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  template <>
  class Chunk<eU_offset> : virtual public Parent 
  {
  public:
    Chunk<eU_offset>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eU_offset; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eU_scale> : virtual public Parent 
  {
  public:
    Chunk<eU_scale>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eU_scale; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eV_offset> : virtual public Parent 
  {
  public:
    Chunk<eV_offset>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eV_offset; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };  

  template <>
  class Chunk<eV_scale> : virtual public Parent 
  {
  public:
    Chunk<eV_scale>()
    {
      cout << "Constr " << id() << endl;
    };
    virtual void foo(){};
    static const enMemberList id() { return eV_scale; }
    virtual void operator>>(ofstream &outMotorFile) {};  
    virtual void operator<<(ifstream &inMotorFile) {};
  };

  //Âîçâðàùàåò óêàçàòåëü íà êëàññ èåðàðõèè êëàññîâ AnimalsHierarchy, 
  //íîìåð êîòîðîãî çàäàí â num
  static Parent * nameToThis(const int & num)
  {
    return Selector<HierarchySubChunksForAllMaps, Parent>::f<0>(num);
  }
 };
#33
19:59, 2 янв. 2010

Выбор нужной специализации чанка при загрузке из файла может производится таким вот несложным селектором:

//Ñåëåêòîð òèïà. Èñïîëüçóåòñÿ ïîñëåäîâàòåëüíûé ïîèñê â ïåðå÷èñëåíèè Hierarchy::enMemberList.
//Âîçðàùàåò óêàçàòåëü íà êëàññ, èìÿ êîòîðîãî çàäàííî â ñòðîêå num.
//Ïðåèìóùåñòâî òàêîãî ñåëåêòîðà â ìåíüøåé çàãðóçêå ñòåêà ïðè áîëüøîì ðàçìåðå ïåðå÷èñëåíèÿ enMemberList.
template <typename Hierarchy,  //Hierarchy - ñòðóêòóðà â êîòîðîé óïàêîâàíà èåðàðõèÿ êëàññîâ
       typename Parent>  //Ïðåäîê âñåõ êëàññîâ Hierarchy       
struct Selector
{
  template <int n>      //èíäåêñ â ïåðå÷èñëåíèè Hierarchy::enMemberList
  static Parent * f(const int & num) 
  {      
    if (num == Hierarchy::enMemberList(n))
      return new Hierarchy::Chunk<Hierarchy::enMemberList(n)>;
    else 
      return f<n + 1>(num);
  }  
  template <>  static Parent * f<Hierarchy::enEndNumber>(const int & num) {return 0;}  
};
#34
0:27, 3 янв. 2010

Аctor пишет ! шестым идет версия а 16 Edit ... так блин что после 6-ого ? 4 байта есть или нет ? и ещё если дальше читать по 6 байт (2 на id чанка 4 на длинну) то на 16 байт ты никак друг не попадешь !

Оказыцца он не договорил: Версия действительно есть, она просто начинаеться с 6 байта, точно также имеет длинну записаную в 4 байта и если нормально прочитать EDIT3D как раз 16 байт ...

О. Федор 

У тебя очень интересные номера чанков, т.е. я такие в первый раз вижу. Не мог ты подсказать где нашел инфу полную. Я в сети нашел тока 1996 года ... там о таких даже речи нет.

И ещё не знаешь может ли 3ds Max в файл *.3ds выгрузить данные скина ??? (может плагин какой нить?)

Заранее премного благодарен.

#35
10:25, 3 янв. 2010

m21448
Делал по 3DSINFO.TXT, сейчас можно найти по адресу http://internettrash.com/users/fdb/3dsinfo.rar.

> И ещё не знаешь может ли 3ds Max в файл *.3ds выгрузить данные скина

Такую инфу еще не встречал.

#36
15:14, 7 мая 2010

А вообще один ObjBlock может содержать только один объект типа сетки, камеры или света или несколько.

Прошло более 9 месяцев
#37
13:00, 18 фев. 2011

Внимание, люди!!
Вот я что проинвестигейлил:
-Для статических (не анимированных) моделей локальная система координат говорит о локальной системе координат для меша. Однако вершины задаются в мировой с.к.
(всем тем кто пишет в статьях и в lib3ds о каких-то преобразованиях вершин из л.с.к. в м с.к. надо руки поотрезать)
-Если вы добавили анимацию, то что-то непонятное происходит. Думаю надо отталкиваться от чего-то из блока анимации для меша(ей) (может от pivot point, не знаю).
Убивает отсутсвие нормальной документации по этому формату, только короткие статьи по чанкам, как буд-то это писали люди котрые расстались с автодеском))
Пожалуйста, посоветуйте документацию по анимации в 3ds, если кто знает.

#38
15:44, 18 фев. 2011

bruzo
> Пожалуйста, посоветуйте документацию по анимации в 3ds, если кто знает.
Формат закрытый, используй другие форматы, с ними гораздо меньше проблем, особенно с открытыми.

Правка: И вообще держи Изображение

#39
15:13, 22 мар. 2011

m21448, от начала 16. первые 6 прочитали. потом + 10. = 16. Возможно, я ошибся.

#40
15:17, 22 мар. 2011

m21448, 3D3D идёт, а дальше не помню как перейти на 4000. Пытаюсь вспомнить.

#41
15:36, 22 мар. 2011

m21448, 16 потому что складываем в уме 6+10. От начала 16 пропускаем и попадаем на 3D3D.
Извиняюсь что некорректно обьясняю.

#42
15:41, 22 мар. 2011

Actor
привет из прошлого, и ты держи
Изображение

#43
16:03, 22 мар. 2011

KpeHDeJIb, открытые форматы, это хорошо, но настаёт время, когда надо шифровать

#44
16:57, 3 апр. 2011

Единственный главный блок в файле формата 3ds, идёт блок 0x4D4D, к котором содержатся все остальные блоки.
Блок 0x4D4D содержит три блока: 0x0002, 0x3D3D, 0xB000.
Блок 0x0002 содержит всего лишь номер версии, поэтому его можно пропустить.
Блок 0x3D3D содержит четыре блока: 0x3D3E, 0xAFFF, 0x0100, 0x4000.
Блок 0xB000 содержит информацию об анимации.

Блоки 0x3D3E и 0x0100 бесполезны, поэтому их пропускаем.

unsigned short id;
unsigned int len, filelen=1, posInFile=0;
FILE *file;

VOID skipChunk(){fseek(file, (len-6), SEEK_CUR); posInFile=ftell(file);}

if(!(file = fopen("имя.3ds", "rb"))){MessageBox(0, _T("Error"), _T("No file"), MB_OK); return;}

while(posInFile<filelen)
{
  posInFile+=2*(int(fread(&id,          2, 1, file)));
  posInFile+=4*(int(fread(&len,          4, 1, file)));

        switch(id)
  {
    case 0x4D4D:{filelen=len;}break;
                      case 0x0002:{skipChunk();}break;
                      case 0x3D3D:{}break;
                              case 0x3D3E:{skipChunk();}break; // этот блок весит 10 байт в нём только указан номер версии, поэтому пропускаем.
                              case 0xAFFF:{skipChunk();}break; // если нужна информация о материале, то не пропускать.
                              case 0x0100:{skipChunk();}break; // этот блок весит 10 байт, поэтому тоже пропускаем.
                              case 0x4000:{skipChunk();}break; // если нужна информация о меше, то не пропускать.
                      case 0xB000:{skipChunk();}break; // если нужна информация об анимации, то не пропускать.
        }
}

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеФорумОбщее

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