void C3DSLoader::ReadNextObjChunk(t3DModel *pModel, t3DObject *pObject, tChunk *pPreChunk)   
{      
	int buffer[50000] = {0};              
	m_CurrentChunk = new tChunk;   
  
	while (pPreChunk->bytesRead < pPreChunk->length)   
	{      
		ReadChunk(m_CurrentChunk);   
  
		switch (m_CurrentChunk->ID)   
		{   
		case OBJ_MESH:                   
			ReadNextObjChunk(pModel, pObject, m_CurrentChunk);   
			break;   
		case OBJ_VERTICES:             
			ReadVertices(pObject, m_CurrentChunk);   
			break;   
		case OBJ_FACES:                  
			ReadVertexIndices(pObject, m_CurrentChunk);   
			break;   
		case OBJ_MATERIAL:              
			ReadObjMat(pModel, pObject, m_CurrentChunk);               
			break;   
		case OBJ_UV:                      
			ReadUVCoordinates(pObject, m_CurrentChunk);   
			break;   
		default:     
			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);   
			break;   
		}      
		pPreChunk->bytesRead += m_CurrentChunk->bytesRead;   
	}   
	delete m_CurrentChunk;   
	m_CurrentChunk = pPreChunk;   
}   
//  下面的函数处理所有的文件中对象的信息
void CLoad3DS::ReadNextObjChunk(t3DModel *pModel, t3DObject *pObject, tChunk *pPreChunk)
{ 
	int buffer[50000] = {0};     // 用于读入不需要的数据
	// 对新的块分配存储空间
	m_CurrentChunk = new tChunk;

	// 继续读入块的内容直至本子块结束
	while (pPreChunk->bytesRead < pPreChunk->length)
	{ // 读入下一个块
		ReadChunk(m_CurrentChunk);
		// 区别读入是哪种块
		switch (m_CurrentChunk->ID)
		{
		case OBJ_MESH:     // 正读入的是一个新块
			// 使用递归函数调用,处理该新块
			ReadNextObjChunk(pModel, pObject, m_CurrentChunk);
			break;
		case OBJ_VERTICES:    // 读入是对象顶点
			ReadVertices(pObject, m_CurrentChunk);
			break;
		case OBJ_FACES:     // 读入的是对象的面
			ReadVertexIndices(pObject, m_CurrentChunk);
			break;
		case OBJ_MATERIAL:    // 读入的是对象的材质名称
			// 该块保存了对象材质的名称,可能是一个颜色,也可能是一个纹理映射。同时在该块中也保存了
			// 纹理对象所赋予的面
			// 下面读入对象的材质名称
			ReadObjMat(pModel, pObject, m_CurrentChunk);   
			break;
		case OBJ_UV:      // 读入对象的UV纹理坐标
			// 读入对象的UV纹理坐标
			ReadUVCoordinates(pObject, m_CurrentChunk);
			break;
		default:  
			// 略过不需要读入的块
			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
			break;
		}
		// 添加从最后块中读入的字节数到前面的读入的字节中
		pPreChunk->bytesRead += m_CurrentChunk->bytesRead;
	}
	// 释放当前块的内存空间,并把当前块设置为前面块
	delete m_CurrentChunk;
	m_CurrentChunk = pPreChunk;
}
void C3DSLoader::ReadNextChunk(t3DModel *pModel, tChunk *pPreChunk)   
{      
	t3DObject newObject = {0};                 
	tMatInfo newTexture = {0};              
	unsigned int version = 0;              
	int buffer[50000] = {0};                
	m_CurrentChunk = new tChunk;             

	while (pPreChunk->bytesRead < pPreChunk->length)   
	{       
		ReadChunk(m_CurrentChunk);   

		switch (m_CurrentChunk->ID)   
		{   

		case VERSION:                              

			m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);   
 
			break;   

		case OBJECTINFO:                           

			ReadChunk(m_TempChunk);   
  
			m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);   
 
			m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;   
  
			ReadNextChunk(pModel, m_CurrentChunk);   
			break;   

		case MATERIAL:                             

			pModel->numOfMaterials++;   
 
			pModel->pMaterials.push_back(newTexture);   

			ReadNextMatChunk(pModel, m_CurrentChunk);   
			break;   

		case OBJECT:                               

			pModel->numOfObjects++;   
 
			pModel->pObject.push_back(newObject);   

			memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));   

			m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);   
 
			ReadNextObjChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);   
			break;   

		case EDITKEYFRAME:   

			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);   
			break;   
		default:    
  
			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);   
			break;   
		}   

		pPreChunk->bytesRead += m_CurrentChunk->bytesRead;   
	}   

	delete m_CurrentChunk;   
	m_CurrentChunk = pPreChunk;   

}    
void CLoad3DS::ReadNextChunk(t3DModel *pModel, tChunk *pPreChunk)
{
	t3DObject newObject = {0};     // 用来添加到对象链表
	tMatInfo newTexture = {0};    // 用来添加到材质链表
	unsigned int version = 0;     // 保存文件版本
	int buffer[50000] = {0};     // 用来跳过不需要的数据

	m_CurrentChunk = new tChunk;    // 为新的块分配空间  
	//  下面每读一个新块,都要判断一下块的ID,如果该块是需要的读入的,则继续进行
	//  如果是不需要读入的块,则略过
	// 继续读入子块,直到达到预定的长度
	while (pPreChunk->bytesRead < pPreChunk->length)
	{
		// 读入下一个块
		ReadChunk(m_CurrentChunk);
		// 判断块的ID号
		switch (m_CurrentChunk->ID)
		{
		case VERSION:       // 文件版本号
			// 在该块中有一个无符号短整型数保存了文件的版本
			// 读入文件的版本号,并将字节数添加到bytesRead变量中
			m_CurrentChunk->bytesRead += fread(&version, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
			// 如果文件版本号大于3,给出一个警告信息
			if (version > 0x03)
				MessageBox(NULL, "This 3DS file is over version 3 so it may load incorrectly", "Warning", MB_OK);
			break;

		case OBJECTINFO:      // 网格版本信息
			// 读入下一个块
			ReadChunk(m_TempChunk);
			// 获得网格的版本号
			m_TempChunk->bytesRead += fread(&version, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);
			// 增加读入的字节数
			m_CurrentChunk->bytesRead += m_TempChunk->bytesRead;
			// 进入下一个块
			ReadNextChunk(pModel, m_CurrentChunk);
			break;

		case MATERIAL:       // 材质信息
			// 材质的数目递增
			pModel->numOfMaterials++;
			// 在纹理链表中添加一个空白纹理结构
			pModel->pMaterials.push_back(newTexture);
			// 进入材质装入函数
			ReadNextMatChunk(pModel, m_CurrentChunk);
			break;

		case OBJECT:       // 对象的名称
			// 该块是对象信息块的头部,保存了对象了名称
			// 对象数递增
			pModel->numOfObjects++;
			// 添加一个新的tObject节点到对象链表中
			pModel->pObject.push_back(newObject);
			// 初始化对象和它的所有数据成员
			memset(&(pModel->pObject[pModel->numOfObjects - 1]), 0, sizeof(t3DObject));
			// 获得并保存对象的名称,然后增加读入的字节数
			m_CurrentChunk->bytesRead += GetString(pModel->pObject[pModel->numOfObjects - 1].strName);
			// 进入其余的对象信息的读入
			ReadNextObjChunk(pModel, &(pModel->pObject[pModel->numOfObjects - 1]), m_CurrentChunk);
			break;

		case EDITKEYFRAME:  
			// 跳过关键帧块的读入,增加需要读入的字节数
			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
			break;

		default: 
			//  跳过所有忽略的块的内容的读入,增加需要读入的字节数
			m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
			break;
		}
		// 增加从最后块读入的字节数
		pPreChunk->bytesRead += m_CurrentChunk->bytesRead;
	}
	// 释放当前块的内存空间
	delete m_CurrentChunk;
	m_CurrentChunk = pPreChunk;
}