#include <stdio.h>
#include <stdlib.h>
char chStr;
strcpy(chStr, "");
всё равно нифига не понятно !
Аctor пишет ! шестым идет версия а 16 Edit ... так блин что после 6-ого ? 4 байта есть или нет ? и ещё если дальше читать по 6 байт (2 на id чанка 4 на длинну) то на 16 байт ты никак друг не попадешь !
Не знаю, что-то мне эти все поделки не очень нравятся. Эти бесконечные свичи и ифы.
Думаю, нужно потихоньку отходить от сищного стиля программирования.
На мой взгляд программа для загрузки 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); } };
Выбор нужной специализации чанка при загрузке из файла может производится таким вот несложным селектором:
//Ñåëåêòîð òèïà. Èñïîëüçóåòñÿ ïîñëåäîâàòåëüíûé ïîèñê â ïåðå÷èñëåíèè 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;} };
Аctor пишет ! шестым идет версия а 16 Edit ... так блин что после 6-ого ? 4 байта есть или нет ? и ещё если дальше читать по 6 байт (2 на id чанка 4 на длинну) то на 16 байт ты никак друг не попадешь !
Оказыцца он не договорил: Версия действительно есть, она просто начинаеться с 6 байта, точно также имеет длинну записаную в 4 байта и если нормально прочитать EDIT3D как раз 16 байт ...
О. Федор
У тебя очень интересные номера чанков, т.е. я такие в первый раз вижу. Не мог ты подсказать где нашел инфу полную. Я в сети нашел тока 1996 года ... там о таких даже речи нет.
И ещё не знаешь может ли 3ds Max в файл *.3ds выгрузить данные скина ??? (может плагин какой нить?)
Заранее премного благодарен.
m21448
Делал по 3DSINFO.TXT, сейчас можно найти по адресу http://internettrash.com/users/fdb/3dsinfo.rar.
> И ещё не знаешь может ли 3ds Max в файл *.3ds выгрузить данные скина
Такую инфу еще не встречал.
А вообще один ObjBlock может содержать только один объект типа сетки, камеры или света или несколько.
Внимание, люди!!
Вот я что проинвестигейлил:
-Для статических (не анимированных) моделей локальная система координат говорит о локальной системе координат для меша. Однако вершины задаются в мировой с.к.
(всем тем кто пишет в статьях и в lib3ds о каких-то преобразованиях вершин из л.с.к. в м с.к. надо руки поотрезать)
-Если вы добавили анимацию, то что-то непонятное происходит. Думаю надо отталкиваться от чего-то из блока анимации для меша(ей) (может от pivot point, не знаю).
Убивает отсутсвие нормальной документации по этому формату, только короткие статьи по чанкам, как буд-то это писали люди котрые расстались с автодеском))
Пожалуйста, посоветуйте документацию по анимации в 3ds, если кто знает.
bruzo
> Пожалуйста, посоветуйте документацию по анимации в 3ds, если кто знает.
Формат закрытый, используй другие форматы, с ними гораздо меньше проблем, особенно с открытыми.
Правка: И вообще держи
m21448, от начала 16. первые 6 прочитали. потом + 10. = 16. Возможно, я ошибся.
m21448, 3D3D идёт, а дальше не помню как перейти на 4000. Пытаюсь вспомнить.
m21448, 16 потому что складываем в уме 6+10. От начала 16 пропускаем и попадаем на 3D3D.
Извиняюсь что некорректно обьясняю.
Actor
привет из прошлого, и ты держи
KpeHDeJIb, открытые форматы, это хорошо, но настаёт время, когда надо шифровать
Единственный главный блок в файле формата 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; // если нужна информация об анимации, то не пропускать.
}
}
Тема в архиве.