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; }