#include "loader3ds.h" #include #include #include "object3d.h" #include "mathTools.h" #include "wxTools.h" #include "texture.h" //#include "tools/debug.h" //#ifndef WX_PRECOMP // #include "wx/wx.h" //#endif //#define SEEK_START 1900 //#define SEEK_CURSOR 1901 // colors #define COLOR_F 0x0010 //цвет задается как 3 x float #define COLOR_24 0x0011 //цвет задается как 3 x unsigned char #define LIN_COLOR_24 0x0012 //цвет задается как 4 x unsigned char #define LIN_COLOR_F 0x0013 //цвет задается как 4 x float // percentage #define INT_PERCENTAGE 0x0030 #define FLOAT_PERCENTAGE 0x0031 #define MAIN3DS 0x4D4D //Main chunk, contains all the other chunks #define ID_VERSION 0x0002 //версия файла #define EDIT3DS 0x3D3D // this is the start of the editor config #define MESH_VERSION 0x3D3E // material entries #define MAT_ENTRY 0xAFFF //секция материалов #define MAT_NAME 0xA000 #define MAT_AMBIENT 0xA010 #define MAT_DIFFUSE 0xA020 #define MAT_SPECULAR 0xA030 #define MAT_SHININESS 0xA040 #define MAT_SHIN2PCT 0xA041 #define MAT_TRANSPARENCY 0xA050 #define MAT_TRANSFALLOF 0xA052 #define MAT_REFLECTBLUR 0xA053 #define MAT_SELFILLUM 0xA084 #define MAT_TRANSFALLOFF 0xA08A #define MAT_SHADING 0xA100 #define MAT_TWO_SIDE 0xA081 #define MAT_ADDITIVE 0xA083 #define MAT_WIRE 0xA085 #define MAT_FACEMAP 0xA088 #define MAT_WIRESIZE 0xA087 //always present, in case of forced wire rendering #define MAT_DECAL 0xA082 #define MAT_TEXMAP 0xA200 #define MAT_MAPNAME 0xA300 //названеи текстуры #define MAT_MAP_TILING 0xA351 //количество повторов текстуры по гориз. и вертик. #define MAT_MAP_TEXBLUR 0xA353 //Blur percent #define MAT_MAP_USCALE 0xA354 #define MAT_MAP_VSCALE 0xA356 #define MAT_MAP_UOFFSET 0xA358 #define MAT_MAP_VOFFSET 0xA35A #define MAT_MAP_ANG 0xA35C #define MAT_TEX2MAP 0xA33A #define MAT_OPACMAP 0xA210 #define MAT_BUMPMAP 0xA230 #define MAT_SPECMAP 0xA204 #define MAT_SHINMAP 0xA33C #define MAT_REFLMAP 0xA220 #define MAT_ACUBIC 0xA310 #define EDIT_CONFIG1 0x0100 #define EDIT_OBJECT 0x4000 #define OBJ_TRIMESH 0x4100 #define TRI_VERTEXLIST 0x4110 #define TRI_VERTEXOPTIONS 0x4111 #define TRI_FACEMAPPING 0x4140 #define TRI_FACELIST 0x4120 //Faces description #define TRI_MAT_GROUP 0x4130 //ASCII название материала #define TRI_SMOOTH_GROUP 0x4150 //Бит на n-ом месте указывает на вхождение грани в n-ую группу сглаживания (всего их понятно 32, столько сколько бит в целом без знака); #define TRI_LOCAL 0x4160 //Local coordinate system #define TRI_VISIBLE 0x4165 //Object color in editor #define OBJ_LIGHT 0x4600 #define OBJ_CAMERA 0x4700 #define EDIT_AMBIENT 0x2100// ambient light // keyframer chunk ids #define KFDATA 0xB000 // the keyframer section #define KFHDR 0xB00A //путь к файлу анимации или Viewport layout (Revision number SHORT) #define KFCURTIME 0xB009 //curframe #define FRAMES 0xB008 // Frames (Start and End) #define OBJECT_NODE_TAG 0xB002 //Mesh information block #define HIERARCHY 0xB030 // Hierarchy position #define NODE_HDR 0xB010 //Object name, parameters and hierarchy father #define PIVOT 0xB013 //Object pivot point #define POS_TRACK_TAG 0xB020 //Position track #define ROT_TRACK_TAG 0xB021 //Rotation track #define SCL_TRACK_TAG 0xB022 //Scale track #define CAM_RANGES 0x4720 #define LIT_OFF 0x4620 #define LIT_SPOT 0x4610 #define LIT_INRANGE 0x4659 #define LIT_OUTRANGE 0x465A #define SPOTLIGHT 0x4610 //------------------------------------------------------------------------------ struct LChunk { unsigned short id; unsigned int len; unsigned int sum; }; //------------------------------------------------------------------------------ /*unsigned long read_material_section ( TTriangles * p_object, FILE * l_file ) { // variables LChunk chunk; LChunk child; char str[30]; LMaterial mat; short sh; GotoChunk(parent); chunk = ReadChunk(); while (chunk.end <= parent.end) { switch (chunk.id) { case MAT_NAME: ReadASCIIZ(str, 30); mat.SetName(str); break; case MAT_AMBIENT: child = ReadChunk(); mat.SetAmbientColor(ReadColor(child)); break; case MAT_DIFFUSE: child = ReadChunk(); mat.SetDiffuseColor(ReadColor(child)); break; case MAT_SPECULAR: child = ReadChunk(); mat.SetSpecularColor(ReadColor(child)); break; case MAT_SHININESS: child = ReadChunk(); mat.SetShininess(ReadPercentage(child)); break; case MAT_TRANSPARENCY: child = ReadChunk(); mat.SetTransparency(ReadPercentage(child)); break; case MAT_SHADING: sh = ReadShort(); switch (sh) { case 0: mat.SetShadingType(sWireframe); break; case 1: mat.SetShadingType(sFlat); break; case 2: mat.SetShadingType(sGouraud); break; case 3: mat.SetShadingType(sPhong); break; case 4: mat.SetShadingType(sMetal); break; } break; case MAT_WIRE: mat.SetShadingType(sWireframe); break; case MAT_TEXMAP: ReadMap(chunk, mat.GetTextureMap1()); break; case MAT_TEX2MAP: ReadMap(chunk, mat.GetTextureMap2()); break; case MAT_OPACMAP: ReadMap(chunk, mat.GetOpacityMap()); break; case MAT_BUMPMAP: ReadMap(chunk, mat.GetBumpMap()); break; case MAT_SPECMAP: ReadMap(chunk, mat.GetSpecularMap()); break; case MAT_REFLMAP: child = ReadChunk(); mat.GetReflectionMap().strength = ReadPercentage(child); SkipChunk(child); child = ReadChunk(); if (child.id != MAT_MAPNAME) { ErrorMsg("L3DS::ReadMaterial - error, expected chunk not found"); return; } ReadASCIIZ(str, 30); if (strcmp(str, "") == 0) strcpy(mat.GetReflectionMap().mapName, "auto"); break; } SkipChunk(chunk); chunk = ReadChunk(); } m_materials.push_back(mat); m_materials[m_materials.size()-1].SetID(m_materials.size()-1); return 0; }*/ //------------------------------------------------------------------------------ /*bool Load3DS( TTriangles * p_object, char * p_filename ) { int i; //Index variable FILE * l_file; //File pointer unsigned short l_chunk_id; //Chunk identifier unsigned int l_chunk_lenght; //Chunk lenght unsigned char l_char; //Char variable unsigned short l_qty; //Number of elements in each chunk unsigned short l_face_flags; //Flag that stores some face information if ( ( l_file = fopen( p_filename, "rb" ) ) == NULL ) return 0; //Open the file long flen=fileLength(p_filename); while ( ftell( l_file ) < flen ) //Loop to scan the whole file { //getche(); //Insert this command for debug (to wait for keypress for each chuck reading) fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_char, 1, 1, l_file ); //Read the chunk header printf( "l_char: %d\n", l_char ); fread( & l_chunk_id, 2, 1, l_file ); //Read the chunk header printf( "ChunkID: %d\n", l_chunk_id ); fread( & l_chunk_lenght, 4, 1, l_file ); //Read the lenght of the chunk printf( "ChunkLenght: %d\n", l_chunk_lenght ); switch ( l_chunk_id ) { //----------------- MAIN3DS ----------------- // Description: Main chunk, contains all the other chunks // Chunk ID: 4d4d // Chunk Lenght: 0 + sub chunks //------------------------------------------- case MAIN3DS: break; //----------------- EDIT3DS ----------------- // Description: 3D Editor chunk, objects layout info // Chunk ID: 3d3d (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case EDIT3DS: break; //--------------- EDIT_OBJECT --------------- // Description: Object block, info for each object // Chunk ID: 4000 (hex) // Chunk Lenght: len(object name) + sub chunks //------------------------------------------- case EDIT_OBJECT: i = 0; do { fread( & l_char, 1, 1, l_file ); p_object->name[i] = l_char; i++; } while ( l_char != '\0' && i < 20 ); break; case MAT_ENTRY: read_material_section(p_object,l_file); break; //--------------- OBJ_TRIMESH --------------- // Description: Triangular mesh, contains chunks for 3d mesh info // Chunk ID: 4100 (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case OBJ_TRIMESH: break; //--------------- TRI_VERTEXL --------------- // Description: Vertices list // Chunk ID: 4110 (hex) // Chunk Lenght: 1 x unsigned short (number of vertices) // + 3 x float (vertex coordinates) x (number of vertices) // + sub chunks //------------------------------------------- case TRI_VERTEXLIST: fread( & l_qty, sizeof( unsigned short ), 1, l_file ); p_object->VertexCount = l_qty; printf( "Number of vertices: %d\n", l_qty ); for ( i = 0; i < l_qty; i++ ) { fread( & p_object->Vertices[i].x, sizeof( float ), 1, l_file ); printf( "Vertices list x: %f\n", p_object->Vertices[i].x ); fread( & p_object->Vertices[i].y, sizeof( float ), 1, l_file ); printf( "Vertices list y: %f\n", p_object->Vertices[i].y ); fread( & p_object->Vertices[i].z, sizeof( float ), 1, l_file ); printf( "Vertices list z: %f\n", p_object->Vertices[i].z ); } break; //--------------- TRI_FACEL1 ---------------- // Description: Polygons (faces) list // Chunk ID: 4120 (hex) // Chunk Lenght: 1 x unsigned short (number of polygons) // + 3 x unsigned short (polygon points) x (number of polygons) // + sub chunks //------------------------------------------- case TRI_FACELIST: fread( & l_qty, sizeof( unsigned short ), 1, l_file ); p_object->FacesCount = l_qty; printf( "Number of polygons: %d\n", l_qty ); //пїЅпїЅпїЅпїЅ пїЅпїЅпїЅ p_object->faces= new RsFacesABC[p_object->FacesCount]; p_object->SmoothNormals= new RfPointXYZ[p_object->FacesCount]; for ( i = 0; i < l_qty; i++ ) { fread( & p_object->faces[i].a, sizeof( unsigned short ), 1, l_file ); printf( "Polygon point a: %d\n", p_object->faces[i].a ); fread( & p_object->faces[i].b, sizeof( unsigned short ), 1, l_file ); printf( "Polygon point b: %d\n", p_object->faces[i].b ); fread( & p_object->faces[i].c, sizeof( unsigned short ), 1, l_file ); printf( "Polygon point c: %d\n", p_object->faces[i].c ); fread( & l_face_flags, sizeof( unsigned short ), 1, l_file ); printf( "Face flags: %x\n", l_face_flags ); //пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ CalcNormals( p_object->Vertices[ p_object->faces[i].a ].x, p_object->Vertices[ p_object->faces[i].a ].y, p_object->Vertices[ p_object->faces[i].a ].z, p_object->Vertices[ p_object->faces[i].b ].x, p_object->Vertices[ p_object->faces[i].b ].y, p_object->Vertices[ p_object->faces[i].b ].z, p_object->Vertices[ p_object->faces[i].c ].x, p_object->Vertices[ p_object->faces[i].c ].y, p_object->Vertices[ p_object->faces[i].c ].z, p_object->SmoothNormals[i].x,p_object->SmoothNormals[i].y,p_object->SmoothNormals[i].z); } break; //------------- TRI_MAPPINGCOORS ------------ // Description: Vertices list // Chunk ID: 4140 (hex) // Chunk Lenght: 1 x unsigned short (number of mapping points) // + 2 x float (mapping coordinates) x (number of mapping points) // + sub chunks //------------------------------------------- case TRI_FACEMAPPING: fread( & l_qty, sizeof( unsigned short ), 1, l_file ); p_object->countMapPoint = l_qty; printf( "Number of MapPoint: %d\n", l_qty ); p_object->TexVertices= new RfPointXY[p_object->countMapPoint]; for ( i = 0; i < l_qty; i++ ) { fread( & p_object->TexVertices[i].x, sizeof( float ), 1, l_file ); printf( "Mapping list u: %f\n", p_object->TexVertices[i].x ); fread( & p_object->TexVertices[i].y, sizeof( float ), 1, l_file ); printf( "Mapping list v: %f\n", p_object->TexVertices[i].y ); } break; //----------- Skip unknow chunks ------------ //We need to skip all the chunks that currently we don't use //We use the chunk lenght information to set the file pointer //to the same level next chunk //------------------------------------------- default: fseek( l_file, l_chunk_lenght - 6, SEEK_CUR ); } } fclose( l_file ); // Closes the file stream return ( 1 ); // Returns ok }*/ void f_MAT_ENTRY(TTrianglesList *MultyMesh,wxInputStream *is,TFileList *fl,unsigned int allLenght) { LChunk chunk1,chunk2; unsigned int i; char l_char; float r,g,b,a,blur; unsigned char br, bg, bb, ba; unsigned short precent,tiling; TTriMat *Material=MultyMesh->AddMat(); //добавляем новую текстуру к списку всех текстур chunk1.sum=0; while(chunk1.sumRead(&chunk1.id, sizeof(chunk1.id)); is->Read(&chunk1.len, sizeof(chunk1.len)); chunk1.sum+=chunk1.len; if(chunk1.sum>allLenght-6) return;//проверка на ошибки в алгоритме считывания switch(chunk1.id) { case MAT_NAME: //создаём новый материал с заданным здесь именем for(i=0;i<20;i++) { is->Read(&l_char, 1); Material->name[i] = l_char; if(l_char==0) break; } break; case MAT_AMBIENT: is->Read(&chunk2.id, sizeof(chunk2.id)); is->Read(&chunk2.len, sizeof(chunk2.len)); switch(chunk2.id) { case COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); break; case COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); break; case LIN_COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); is->Read(&ba, sizeof(ba)); break; case LIN_COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); is->Read(&a, sizeof(a)); break; } Material->ColorAmbientRGB.r=br/255.0f; Material->ColorAmbientRGB.g=bg/255.0f; Material->ColorAmbientRGB.b=bb/255.0f; break; case MAT_DIFFUSE: is->Read(&chunk2.id, sizeof(chunk2.id)); is->Read(&chunk2.len, sizeof(chunk2.len)); switch(chunk2.id) { case COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); break; case COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); break; case LIN_COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); is->Read(&ba, sizeof(ba)); break; case LIN_COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); is->Read(&a, sizeof(a)); break; } Material->ColorDiffuseRGB.r=br/255.0f; Material->ColorDiffuseRGB.g=bg/255.0f; Material->ColorDiffuseRGB.b=bb/255.0f; break; case MAT_SPECULAR: is->Read(&chunk2.id, sizeof(chunk2.id)); is->Read(&chunk2.len, sizeof(chunk2.len)); switch(chunk2.id) { case COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); break; case COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); break; case LIN_COLOR_24: is->Read(&br, sizeof(br)); is->Read(&bg, sizeof(bg)); is->Read(&bb, sizeof(bb)); is->Read(&ba, sizeof(ba)); break; case LIN_COLOR_F: is->Read(&r, sizeof(r)); is->Read(&g, sizeof(g)); is->Read(&b, sizeof(b)); is->Read(&a, sizeof(a)); break; } Material->ColorSpecularRGB.r=br/255.0f; Material->ColorSpecularRGB.g=bg/255.0f; Material->ColorSpecularRGB.b=bb/255.0f; break; case MAT_SHININESS: for(i=0;iRead(&l_char,1); break; case MAT_SHIN2PCT: for(i=0;iRead(&l_char,1); break; case MAT_TRANSPARENCY: for(i=0;iRead(&l_char,1); break; case MAT_TRANSFALLOF: for(i=0;iRead(&l_char,1); break; case MAT_REFLECTBLUR: for(i=0;iRead(&l_char,1); break; case MAT_SHADING: for(i=0;iRead(&l_char,1); break; case MAT_SELFILLUM: for(i=0;iRead(&l_char,1); break; case MAT_TRANSFALLOFF: for(i=0;iRead(&l_char,1); break; case MAT_WIRESIZE: for(i=0;iRead(&l_char,1); break; // case MAT_TRANSPARENCY: // break; // case MAT_TEXMAP: // ProcessNextMaterialChunk(NewChunk); // break; case MAT_TEXMAP: chunk2.sum=0; while(chunk2.sumRead(&chunk2.id, sizeof(chunk2.id)); is->Read(&chunk2.len, sizeof(chunk2.len)); chunk2.sum+=chunk2.len; switch(chunk2.id) { case INT_PERCENTAGE: is->Read(&precent, sizeof(precent)); break; case MAT_MAPNAME: //файл текстуры { for(i=0;i<20;i++) { is->Read(&l_char, 1); Material->imgpath[i] = l_char; if(l_char==0) break; } //находим текстуру в архиве и загружаем wxInputStream *imgStream = fl->get(wxString::FromAscii(Material->imgpath)); if(imgStream!=NULL) { wxString ext=getAfterLast(wxString::FromAscii(Material->imgpath),'.'); Material->textureid=glLoadBitmap0(2,*imgStream,ext); } } break; case MAT_MAP_TILING: is->Read(&tiling, sizeof(tiling)); break; case MAT_MAP_TEXBLUR: is->Read(&blur, sizeof(blur)); break; case MAT_MAP_USCALE: is->Read(&Material->USCALE, sizeof(Material->USCALE)); break; case MAT_MAP_VSCALE: is->Read(&Material->VSCALE, sizeof(Material->VSCALE)); break; case MAT_MAP_UOFFSET: for(i=0;iRead(&l_char,1); break; case MAT_MAP_VOFFSET: for(i=0;iRead(&l_char,1); break; default: for(i=0;iRead(&l_char,1); //непрочитанные блоки пропускаем } } break; default: for(i=0;iRead(&l_char,1); //непрочитанные блоки пропускаем } } //result=allLenght; } //------------------------------------------------------------------------------ bool LoadMain3DS(TTrianglesList *MultyMesh,wxInputStream *is,TFileList *fl) { LChunk chunk1,chunk2,chunk3,chunk4,chunk5; //unsigned short bufus; unsigned short wpos=0; unsigned short l_qty,l_face_flags; unsigned int Version,i; unsigned char l_char; RfPointXYZ xPoint1,yPoint2,zPoint3; TTriangles *p_object; unsigned int size=(unsigned int)is->GetSize(); chunk1.sum=0; while(chunk1.sumRead(&chunk1.id, 2); is->Read(&chunk1.len, 4); chunk1.sum+=chunk1.len; if(chunk1.sum>size-6) return false;//проверка на ошибки в алгоритме считывания switch(chunk1.id) { case ID_VERSION: is->Read(&Version, 4); if(Version>3) return false; break; //----------------- EDIT3DS ----------------- // Description: 3D Editor chunk, objects layout info // Chunk ID: 3d3d (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case EDIT3DS: chunk2.sum=0; while(chunk2.sumRead(&chunk2.id, sizeof(chunk2.id)); is->Read(&chunk2.len, sizeof(chunk2.len)); chunk2.sum+=chunk2.len; if(chunk2.sum>chunk1.len-6) return false;//проверка на ошибки в алгоритме считывания switch(chunk2.id) { //по правильному надо поместить всё что ниже сюда case MESH_VERSION: is->Read(&Version, 4); if(Version>3) return false; break; case MAT_ENTRY: f_MAT_ENTRY(MultyMesh,is,fl,chunk2.len); break; case EDIT_CONFIG1: for(i=0;iRead(&l_char,1); break; //--------------- EDIT_OBJECT --------------- // Description: Object block, info for each object // Chunk ID: 4000 (hex) // Chunk Lenght: len(object name) + sub chunks //------------------------------------------- case EDIT_OBJECT: p_object=MultyMesh->Add(); wpos=0; //позиция загружаемой текстуры char cnt=0; for(i=0;i<20;i++) //считываем название обьекта { is->Read(&l_char, 1); p_object->name[i] = l_char; cnt++; if(l_char==0) break; } chunk3.sum=0; while(chunk3.sumRead(&chunk3.id, sizeof(chunk3.id)); is->Read(&chunk3.len, sizeof(chunk3.len)); chunk3.sum+=chunk3.len; if(chunk3.sum>chunk2.len-6-cnt) return false;//проверка на ошибки в алгоритме считывания switch(chunk3.id) { //--------------- OBJ_TRIMESH --------------- // Description: Triangular mesh, contains chunks for 3d mesh info // Chunk ID: 4100 (hex) // Chunk Lenght: 0 + sub chunks //------------------------------------------- case OBJ_TRIMESH: chunk4.sum=0; while(chunk4.sumRead(&chunk4.id, sizeof(chunk4.id)); is->Read(&chunk4.len, sizeof(chunk4.len)); chunk4.sum+=chunk4.len; if(chunk4.sum>chunk3.len-6) return false;//проверка на ошибки в алгоритме считывания switch(chunk4.id) { //--------------- TRI_VERTEXL --------------- // Description: Vertices list // Chunk ID: 4110 (hex) // Chunk Lenght: 1 x unsigned short (number of vertices) // + 3 x float (vertex coordinates) x (number of vertices) // + sub chunks //------------------------------------------- case TRI_VERTEXLIST: is->Read(&l_qty,2); p_object->CountVertex = l_qty; p_object->Vertices=new RfPointXYZ[p_object->CountVertex]; //память под точки for(i=0;iRead(&p_object->Vertices[i].x, 4); is->Read(&p_object->Vertices[i].y, 4); is->Read(&p_object->Vertices[i].z, 4); } //p_object->CalcMinMaxPoint(); break; //--------------- TRI_FACEL1 ---------------- // Description: Polygons (faces) list // Chunk ID: 4120 (hex) // Chunk Lenght: 1 x unsigned short (number of polygons) // + 3 x unsigned short (polygon points) x (number of polygons) // + sub chunks //------------------------------------------- case TRI_FACELIST: is->Read(&l_qty, 2); p_object->CountFaces = l_qty; p_object->faces=new RsFacesABC[p_object->CountFaces]; //пока сюда не записываем только в буфер потом из буфера в соответствии с текстурой (точки на которые указывает поверхность с другой текстурой надо скопировать (также и с нормалями) ) //bufFaces=new RsFacesABC[p_object->FacesCount]; chunk5.sum=2; //подсчитываем прочитанное for(i=0;iRead(&p_object->faces[i].a, 2); is->Read(&p_object->faces[i].b, 2); is->Read(&p_object->faces[i].c, 2); is->Read(&l_face_flags,2); //word Face flag * bit 0 : CA visible * bit 1 : BC visible * bit 2 : AB visible chunk5.sum+=8; //подсчитываем прочитанное } while(chunk5.sumRead(&chunk5.id, sizeof(chunk5.id)); is->Read(&chunk5.len, sizeof(chunk5.len)); chunk5.sum+=chunk5.len; if(chunk5.sum>chunk4.len-6) return false;//проверка на ошибки в алгоритме считывания switch(chunk5.id) { case TRI_MAT_GROUP: //16688 0x4130 материал для фейсов данного объекта { char *name=new char[20]; for(i=0;i<20;i++)//название материала { is->Read(&l_char, 1); name[i] = l_char; if(l_char==0) break; } unsigned short wnum; is->Read(&wnum,sizeof(wnum)); unsigned short *faces=new unsigned short[wnum]; for(i=0;iRead(&faces[i],2); //список фейсов с данным материалом name p_object->AddMaterial(name,wnum,faces); //фиксируем материал для текущего обьекта на нужной позиции pos } break; case TRI_SMOOTH_GROUP: //0x4150 группа сглаживания для каждого фейса p_object->SmoothG=new unsigned int[p_object->CountFaces]; for(i=0;iCountFaces;i++) { is->Read(&p_object->SmoothG[i],4); } break; default: for(i=0;iRead(&l_char,1); } } break; //------------- TRI_MAPPINGCOORS ------------ // Description: Vertices list // Chunk ID: 4140 (hex) // Chunk Lenght: 1 x unsigned short (number of mapping points) // + 2 x float (mapping coordinates) x (number of mapping points) // + sub chunks //------------------------------------------- case TRI_FACEMAPPING: //координаты материала is->Read(&l_qty, 2); //количество матерных точек == кол-ву точек p_object->TexVertices=new RfPointXY[l_qty]; for(i=0;iRead(&p_object->TexVertices[i].x,sizeof(p_object->TexVertices[i].x)); is->Read(&p_object->TexVertices[i].y,sizeof(p_object->TexVertices[i].y)); } break; case TRI_LOCAL: //Local coordinate system //Max сохраняет в 3ds уже с конвертированное а всё в этом чанке только для информации is->Read(&xPoint1.x,sizeof(xPoint1.x)); //Scale X "Absolute: Local" is->Read(&xPoint1.y,sizeof(xPoint1.z)); is->Read(&xPoint1.z,sizeof(xPoint1.y)); is->Read(&yPoint2.x,sizeof(yPoint2.x)); is->Read(&yPoint2.y,sizeof(yPoint2.y)); //Scale Y "Absolute: Local" is->Read(&yPoint2.z,sizeof(yPoint2.z)); is->Read(&zPoint3.x,sizeof(zPoint3.x)); is->Read(&zPoint3.y,sizeof(zPoint3.y)); is->Read(&zPoint3.z,sizeof(zPoint3.z)); //Scale Z "Absolute: Local" is->Read(&p_object->PointXYZCenter.x,sizeof(p_object->PointXYZCenter.x)); //позизия пивота в абсолютных координатах (надо найти разницу) is->Read(&p_object->PointXYZCenter.y,sizeof(p_object->PointXYZCenter.y)); is->Read(&p_object->PointXYZCenter.z,sizeof(p_object->PointXYZCenter.z)); break; default: for(i=0;iRead(&l_char,1); }//end of switch(l_chunk_id4) }//end of while(sumLenght4Read(&l_char,1); break; case OBJ_CAMERA: for(i=0;iRead(&l_char,1); break; default: for(i=0;iRead(&l_char,1); }//end of switch(l_chunk_id3) }//end of while(sumLenght3Read(&l_char,1); } }//end of while(sumLenght2Read(&l_char,1); /* sumLenght2=0; while(sumLenght2Read(&l_chunk_id2, sizeof(l_chunk_id2)); is->Read(&l_chunk_lenght2, sizeof(l_chunk_lenght2)); sumLenght2=sumLenght2 + l_chunk_lenght2; if(sumLenght2>l_chunk_lenght-6) return false;//проверка на ошибки в алгоритме считывания switch(l_chunk_id2) { case KFHDR: // путь к файлу анимации или Viewport layout (Revision number SHORT) { is->Read(&bufus, sizeof(bufus)); //Revision number (версия файла) for(i=0;i<20;i++) { is->Read(&l_char, 1); name[i] = l_char; if(l_char=='\n') break; } is->Read(&bufus, sizeof(bufus)); //Animation length is->Read(&bufus, sizeof(bufus)); //старт ??? } case FRAMES: //Object name, parameters and hierarchy father { is->Read(&fstart, sizeof(fstart)); is->Read(&fend, sizeof(fend)); } case KFCURTIME: { is->Read(&bufus, sizeof(bufus)); is->Read(&bufus, sizeof(bufus)); } case OBJECT_NODE_TAG: { sumLenght3=0; while(sumLenght3Read(&l_chunk_id3, sizeof(l_chunk_id3)); is->Read(&l_chunk_lenght3, sizeof(l_chunk_lenght3)); sumLenght3=sumLenght3 + l_chunk_lenght3; if(sumLenght3>l_chunk_lenght2-6) return false;//проверка на ошибки в алгоритме считывания switch(l_chunk_id3) { case HIERARCHY: //45104 : Hierarchy position { //is->seek( l_chunk_lenght3 - 6, soCurrent ); for(i=0;iRead(&l_char,1); } case NODE_HDR: //Object name, parameters and hierarchy father { for(i=0;i<20;i++) { is->Read(&l_char, 1); name[i] = l_char; if(l_char=='\n') break; } p_object=MultyMesh->FindObjectOnName(name); is->Read(&wnum, sizeof(wnum)); //* Bit 11 : Hidden is->Read(&wnum, sizeof(wnum)); //* Bit 0 : Show path * Bit 1 : Animate smoothing * Bit 4 : Object motion blur * Bit 6 : Morph MultyMesh-> is->Read(&wnum, sizeof(wnum)); // Hierarchy father, link to the parent object (-1 for none) } case PIVOT: { //Считываем на сколько был сдвинут пивот по XYZ от первоначального значения (в 3d Максе ) is->Read(&PivotPoint.x, sizeof(PivotPoint.x)); is->Read(&PivotPoint.y, sizeof(PivotPoint.y)); is->Read(&PivotPoint.z, sizeof(PivotPoint.z)); //при сохранении в 3ds координаты преобразовываються относительно Пивота (поэтому надо их сдвинуть на место) for(i=0;iVertexCount;i++) { p_object->Vertices[i].x=p_object->Vertices[i].x-PivotPoint.x; p_object->Vertices[i].y=p_object->Vertices[i].y-PivotPoint.y; p_object->Vertices[i].z=p_object->Vertices[i].z-PivotPoint.z; } } case POS_TRACK_TAG: //Position track { is->Read(&wnum, sizeof(wnum)); is->Read(&wnum, sizeof(wnum)); is->Read(&wnum, sizeof(wnum)); is->Read(&lwcount, sizeof(lwcount)); //Number of keys in this track is->Read(&lwcn, sizeof(lwcn)); //Key number (position in track) is->Read(&wnum, sizeof(wnum)); //Acceleration data present (flag) is->Read(&CenterPoint.x, sizeof(CenterPoint.x)); is->Read(&CenterPoint.y, sizeof(CenterPoint.x)); is->Read(&CenterPoint.z, sizeof(CenterPoint.y)); is->Read(&CenterPoint.z, sizeof(CenterPoint.z)); } case ROT_TRACK_TAG: //Rotation track 36 bytes { is->Read(&wnum, sizeof(wnum)); is->Read(&wnum, sizeof(wnum)); is->Read(wnum, sizeof(wnum)); is->Read(&wnum, sizeof(wnum)); //Number of keys in this track is->Read(&wnum, sizeof(wnum)); //Key number (position in track) is->Read(&wnum, sizeof(wnum)); //Acceleration data present (flag) is->Read(&lwcn, sizeof(lwcn)); //long unknown; is->Read(&angle, sizeof(angle)); //long unknown; is->Read(&angle, sizeof(angle)); //наверно угол в плоскости X Y пивота //надо подробно разобрать первое предположение что это тоже углы но зачем хватило бы 2 is->Read(&CenterPoint.y, sizeof(CenterPoint.x)); is->Read(&CenterPoint.z, sizeof(CenterPoint.z)); is->Read(&CenterPoint.x, sizeof(CenterPoint.y)); } case SCL_TRACK_TAG: //Scale track { is->Read(&wnum, sizeof(wnum)); //word is->Read(&wnum, sizeof(wnum)); is->Read(wnum, sizeof(wnum)); is->Read(&lwcount, sizeof(lwcount)); //Number of keys in this track is->Read(&lwcn, sizeof(lwcn)); //Key number (position in track) is->Read(&wnum, sizeof(wnum)); //Acceleration data present (flag) is->Read(&CenterPoint.x, sizeof(CenterPoint.x)); is->Read(&CenterPoint.x, sizeof(CenterPoint.x)); //зум по осям 0..1.. is->Read(&CenterPoint.y, sizeof(CenterPoint.y)); is->Read(&CenterPoint.z, sizeof(CenterPoint.z)); } default: //is->seek( l_chunk_lenght3 - 6, soCurrent ); for(i=0;iRead(&l_char,1); } } } default: is->seek( l_chunk_lenght2 - 6, soCurrent ); } //switch } //while*/ break; default: //is->SeekI( l_chunk_lenght - 6, wxFromCurrent ); //непрочитанные блоки пропускаем for(i=0;iRead(&l_char,1); } //switch } //while return true; } //------------------------------------------------------------------------------ //загрузить 3ds файл в объект отображения bool Load3DS2(TTrianglesList *MultyMesh,wxInputStream *is,TFileList *fl) { bool result=true; unsigned short l_chunk_id; unsigned int l_chunk_lenght; unsigned int sumLenght=0; unsigned char l_char; unsigned int size=(unsigned int)is->GetSize(); while(sumLenghtRead(&l_chunk_id, 2); is->Read(&l_chunk_lenght, 4); sumLenght+=l_chunk_lenght; if(sumLenght>size) return false;//проверка на ошибки в алгоритме считывания switch(l_chunk_id) { case MAIN3DS: LoadMain3DS(MultyMesh,is,fl); break; default: for(unsigned int i=0;iRead(&l_char,1); } } return result; } //------------------------------------------------------------------------------ //Загрузить модели из списка именованных потоков // fl - список из "название файла -> поток" // Triangles - Список 3d объектов bool Load3DSFromZIP(TTrianglesList * Triangles,TFileList *fl) { //перебираем и загружаем 3ds файлы for(unsigned int i=0;igetCount();i++) { wxString name=fl->item(i)->name; if(name.AfterLast(_T('.')).Lower()==_T("3ds")) Load3DS2(Triangles,fl->item(i)->is,fl); } return true; } //------------------------------------------------------------------------------