1021 lines
39 KiB
C++
1021 lines
39 KiB
C++
#include "loader3ds.h"
|
||
|
||
#include <wx/stream.h>
|
||
#include <wx/archive.h>
|
||
|
||
#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.sum<allLenght-6)
|
||
{
|
||
is->Read(&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;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_SHIN2PCT:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_TRANSPARENCY:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_TRANSFALLOF:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_REFLECTBLUR:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_SHADING:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_SELFILLUM:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_TRANSFALLOFF:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_WIRESIZE:
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
// case MAT_TRANSPARENCY:
|
||
// break;
|
||
// case MAT_TEXMAP:
|
||
// ProcessNextMaterialChunk(NewChunk);
|
||
// break;
|
||
case MAT_TEXMAP:
|
||
chunk2.sum=0;
|
||
while(chunk2.sum<chunk1.len-6)
|
||
{
|
||
is->Read(&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;i<chunk2.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case MAT_MAP_VOFFSET:
|
||
for(i=0;i<chunk2.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
default: for(i=0;i<chunk2.len-6;i++) is->Read(&l_char,1); //непрочитанные блоки пропускаем
|
||
}
|
||
}
|
||
break;
|
||
default: for(i=0;i<chunk1.len-6;i++) is->Read(&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.sum<size-6)
|
||
{
|
||
is->Read(&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.sum<chunk1.len-6)
|
||
{
|
||
is->Read(&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;i<chunk2.len-6;i++) is->Read(&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.sum<chunk2.len-6-cnt)
|
||
{
|
||
is->Read(&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.sum<chunk3.len-6)
|
||
{
|
||
is->Read(&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;i<l_qty;i++)
|
||
{
|
||
is->Read(&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;i<l_qty;i++)
|
||
{
|
||
is->Read(&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.sum<chunk4.len-6)
|
||
{
|
||
//считываем группы сглаживания для фейсов и материал для фейсов
|
||
is->Read(&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;i<wnum;i++) is->Read(&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;i<p_object->CountFaces;i++)
|
||
{
|
||
is->Read(&p_object->SmoothG[i],4);
|
||
}
|
||
break;
|
||
default:
|
||
for(i=0;i<chunk5.len-6;i++) is->Read(&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;i<l_qty;i++)
|
||
{
|
||
is->Read(&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;i<chunk4.len-6;i++) is->Read(&l_char,1);
|
||
}//end of switch(l_chunk_id4)
|
||
}//end of while(sumLenght4<l_chunk_lenght-6)
|
||
break;
|
||
case OBJ_LIGHT:
|
||
for(i=0;i<chunk3.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
case OBJ_CAMERA:
|
||
for(i=0;i<chunk3.len-6;i++) is->Read(&l_char,1);
|
||
break;
|
||
default:
|
||
for(i=0;i<chunk3.len-6;i++) is->Read(&l_char,1);
|
||
}//end of switch(l_chunk_id3)
|
||
}//end of while(sumLenght3<l_chunk_lenght2-6-cnt)
|
||
break;
|
||
for(i=0;i<chunk2.len-6;i++) is->Read(&l_char,1);
|
||
}
|
||
}//end of while(sumLenght2<l_chunk_lenght-6)
|
||
break;
|
||
case KFDATA: //0xB000 ключи анимации
|
||
for(i=0;i<chunk1.len-6;i++) is->Read(&l_char,1);
|
||
/* sumLenght2=0;
|
||
while(sumLenght2<l_chunk_lenght-6)
|
||
{
|
||
is->Read(&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(sumLenght3<l_chunk_lenght2-6)
|
||
{
|
||
is->Read(&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;i<l_chunk_lenght3-6;i++) is->Read(&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;i<p_object->VertexCount;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;i<l_chunk_lenght3-6;i++) is->Read(&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;i<chunk1.len-6;i++) is->Read(&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(sumLenght<size)
|
||
{
|
||
is->Read(&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;i<l_chunk_lenght-6;i++) is->Read(&l_char,1);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
//Загрузить модели из списка именованных потоков
|
||
// fl - список из "название файла -> поток"
|
||
// Triangles - Список 3d объектов
|
||
bool Load3DSFromZIP(TTrianglesList * Triangles,TFileList *fl)
|
||
{
|
||
//перебираем и загружаем 3ds файлы
|
||
for(unsigned int i=0;i<fl->getCount();i++)
|
||
{
|
||
wxString name=fl->item(i)->name;
|
||
if(name.AfterLast(_T('.')).Lower()==_T("3ds"))
|
||
Load3DS2(Triangles,fl->item(i)->is,fl);
|
||
}
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------------
|