3dsloader.cpp
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:7k
- #include <iostream.h>
- #include <fstream>
- #include "3dsloader.h"
- CLoader3DS::CLoader3DS()
- {
- m_pCurrentMesh = NULL;
- m_pCurrentObject = NULL;
- m_pCurrentMaterial = NULL;
- tm = NULL;
- }
- CLoader3DS::~CLoader3DS()
- {
- }
- bool CLoader3DS::Load( std::string filename, CObject* pObj )
- {
- //ifstream file;
- FILE* file;
- bool doneloading = false;
- int filelength;
- char* memfile; // file loaded into memory
- tm = Texture::GetInstance();
- m_pCurrentObject = pObj;
- file = fopen( filename.c_str(), "rb" );
- if (file == NULL)
- return false;
- fseek( file, 0, SEEK_END );
- filelength = ftell( file );
- memfile = new char[ filelength ];
- fseek( file, 0, SEEK_SET );
- fread( memfile, filelength, 1, file );
- // parse it
- EatChunk(memfile);
- delete memfile;
- fclose( file );
- return true;
- }
- // EatChunk
- //
- // This function recursively handles chunks
- // in a .3ds file. When the function exits,
- // the return value (i) should be the length
- // of the current chunk. Right now we only
- // create one model (the first one listed in
- // the file) and read in verts and polys only.
- // To grab other info from the file, create
- // a new case label in the switch statement
- // for the chunk type you want to react to.
- //
- long CLoader3DS::EatChunk(char* buffer)
- {
- unsigned short chunkid;
- long chunklength;
- int i = 0; // index into current chunk
- int j;
- char name[128];
- int pos;
- int temp;
- chunkid = *(unsigned short*)(buffer);
- chunklength = *(long*)(buffer+2);
- i = 6;
- switch (chunkid)
- {
- case 0x4D4D: // main file
- while ((*(unsigned short*)(buffer+i) != 0x3D3D) &&
- (*(unsigned short*)(buffer+i) != 0xB000))
- i += 2;
- break;
- case 0x3D3D: // editor data
- break;
- case 0x4000: // object description
- m_pCurrentMesh = new CMesh();
- ZeroMemory( m_pCurrentMesh, sizeof(CMesh) );
- m_pCurrentMesh->m_strName = ( (char*)(buffer+i) );
- m_pCurrentObject->AddMesh( m_pCurrentMesh );
- while (*(buffer+(i++)) != 0); // get past string description
- break;
- case 0x4100: // triangular polygon list
- break;
- case 0x4110: // vertex list
- if (m_pCurrentMesh == NULL)
- {
- i = chunklength;
- break;
- }
- if (m_pCurrentMesh->m_dwVertexCount == 0)
- {
- m_pCurrentMesh->m_dwVertexCount = *(unsigned short*)(buffer+i);
- i+=2;
- m_pCurrentMesh->m_pVertices = new CVertex[m_pCurrentMesh->m_dwVertexCount];
- ZeroMemory( m_pCurrentMesh->m_pVertices, m_pCurrentMesh->m_dwVertexCount * sizeof(CVertex) );
- for (j=0;j<m_pCurrentMesh->m_dwVertexCount;j++)
- {
- m_pCurrentMesh->m_pVertices[j].x = *(float*)(buffer+i);
- i+=4;
- m_pCurrentMesh->m_pVertices[j].z = *(float*)(buffer+i);
- i+=4;
- m_pCurrentMesh->m_pVertices[j].y = *(float*)(buffer+i);
- i+=4;
- }
- }
- else
- i = chunklength;
- break;
- case 0x4120:
- if (m_pCurrentMesh == NULL)
- {
- i = chunklength;
- break;
- }
- if (m_pCurrentMesh->m_dwIndexCount == 0)
- {
- m_pCurrentMesh->m_dwIndexCount = *(unsigned short*)(buffer+i);
- m_pCurrentMesh->m_dwIndexCount *= 3;
- i+=2;
- m_pCurrentMesh->m_pIndices = new unsigned short[m_pCurrentMesh->m_dwIndexCount];
- ZeroMemory( m_pCurrentMesh->m_pIndices, m_pCurrentMesh->m_dwIndexCount * sizeof(unsigned short) );
- for (j=0;j<m_pCurrentMesh->m_dwIndexCount/3;j++)
- {
- m_pCurrentMesh->m_pIndices[ j*3 + 0 ] = *(unsigned short*)(buffer+i);
- i+=2;
- m_pCurrentMesh->m_pIndices[ j*3 + 1 ] = *(unsigned short*)(buffer+i);
- i+=2;
- m_pCurrentMesh->m_pIndices[ j*3 + 2 ] = *(unsigned short*)(buffer+i);
- i+=2;
- i+=2; // skip face info
- }
- }
- else
- i = chunklength;
- break;
- case 0x4130:
- if (m_pCurrentMesh == NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMesh->m_strMaterialName = (char*)(buffer+i);
- while (*(buffer+(i++)) != 0); // get past string description
- temp = *(short*)(buffer+i);
- i += sizeof(short) * temp;
- break;
- case 0x4140:
- if (m_pCurrentMesh == NULL)
- {
- i = chunklength;
- break;
- }
- if (m_pCurrentMesh->m_dwVertexCount!=0)
- {
- temp = *(short*)(buffer+i);
- i+=2;
- for( int j=0; j<temp; j++ )
- {
- m_pCurrentMesh->m_pVertices[ j ].tu = *(float*)(buffer+i);
- i+=4;
- m_pCurrentMesh->m_pVertices[ j ].tv = *(float*)(buffer+i);
- i+=4;
- m_pCurrentMesh->m_pVertices[ j ].tu *= -1.0f;
- }
- }
- else
- i = chunklength;
- break;
- case 0xAFFF:
- m_pCurrentMaterial = new CMaterial();
- m_pCurrentObject->AddMaterial( m_pCurrentMaterial );
- m_pCurrentMaterial->m_fUScale = 1.0f;
- m_pCurrentMaterial->m_fVScale = 1.0f;
- break;
- case 0xA000:
- if (m_pCurrentMaterial==NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMaterial->m_strName = (char*)(buffer+i);
- while (*(buffer+(i++)) != 0); // get past string description
- break;
- case 0xA200:
- if (m_pCurrentMaterial==NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMaterial->m_bHasTexture = true;
- break;
- case 0xA300:
- if (m_pCurrentMaterial==NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMaterial->m_strTextureName = (char*)(buffer+i);
- while (*(buffer+(i++)) != 0); // get past string description
- break;
- case 0xA354:
- if (m_pCurrentMaterial==NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMaterial->m_fVScale = *(float*)(buffer+i);
- i+=4;
- break;
- case 0xA356:
- if (m_pCurrentMaterial==NULL)
- {
- i = chunklength;
- break;
- }
- m_pCurrentMaterial->m_fUScale = *(float*)(buffer+i);
- i+=4;
- break;
- default:
- i = chunklength; // skips over rest of chunk (ignores it)
- break;
- }
- // eat child chunks
- while (i < chunklength)
- i += EatChunk(buffer+i);
- return chunklength;
- }