?? 3dsloader.cpp
字號:
/** 關鍵幀 */
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 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: /**< 讀入對象的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::ReadNextMatChunk(t3DModel *pModel, tChunk *pPreChunk)
{
int buffer[50000] = {0}; /**< 用于讀入不需要的數據 */
/** 給當前塊分配存儲空間 */
m_CurrentChunk = new tChunk;
/** 繼續讀入這些塊 */
while (pPreChunk->bytesRead < pPreChunk->length)
{
/** 讀入下一塊 */
ReadChunk(m_CurrentChunk);
/** 判斷讀入的是什么塊 */
switch (m_CurrentChunk->ID)
{
case MATNAME: /**< 材質的名稱 */
/** 讀入材質的名稱 */
m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strName, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
break;
case MATDIFFUSE: /**< 對象的R G B顏色 */
ReadColor(&(pModel->pMaterials[pModel->numOfMaterials - 1]), m_CurrentChunk);
break;
case MATMAP: /**< 紋理信息的頭部 */
/** 下一個材質塊信息 */
ReadNextMatChunk(pModel, m_CurrentChunk);
break;
case MATMAPFILE: /**< 材質文件的名稱 */
/** 讀入材質的文件名稱 */
m_CurrentChunk->bytesRead += fread(pModel->pMaterials[pModel->numOfMaterials - 1].strFile, 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;
}
/** 讀入RGB顏色 */
void C3DSLoader::ReadColor(tMatInfo *pMaterial, tChunk *pChunk)
{
/** 讀入顏色塊信息 */
ReadChunk(m_TempChunk);
/** 讀入RGB顏色 */
m_TempChunk->bytesRead += fread(pMaterial->color, 1, m_TempChunk->length - m_TempChunk->bytesRead, m_FilePointer);
/** 增加讀入的字節數 */
pChunk->bytesRead += m_TempChunk->bytesRead;
}
/** 讀入頂點索引 */
void C3DSLoader::ReadVertexIndices(t3DObject *pObject, tChunk *pPreChunk)
{
unsigned short index = 0; /**< 用于讀入當前面的索引 */
/** 讀入該對象中面的數目 */
pPreChunk->bytesRead += fread(&pObject->numOfFaces, 1, 2, m_FilePointer);
/** 分配所有面的存儲空間,并初始化結構 */
pObject->pFaces = new tFace [pObject->numOfFaces];
memset(pObject->pFaces, 0, sizeof(tFace) * pObject->numOfFaces);
/** 遍歷對象中所有的面 */
for(int i = 0; i < pObject->numOfFaces; i++)
{ for(int j = 0; j < 4; j++)
{
/** 讀入當前面的第一個點 */
pPreChunk->bytesRead += fread(&index, 1, sizeof(index), m_FilePointer);
if(j < 3)
{
/** 將索引保存在面的結構中 */
pObject->pFaces[i].vertIndex[j] = index;
}
}
}
}
/** 讀入對象的UV坐標 */
void C3DSLoader::ReadUVCoordinates(t3DObject *pObject, tChunk *pPreChunk)
{
/** 讀入UV坐標的數量 */
pPreChunk->bytesRead += fread(&pObject->numTexVertex, 1, 2, m_FilePointer);
/** 分配保存UV坐標的內存空間 */
pObject->pTexVerts = new Vector2 [pObject->numTexVertex];
/** 讀入紋理坐標 */
pPreChunk->bytesRead += fread(pObject->pTexVerts, 1, pPreChunk->length - pPreChunk->bytesRead, m_FilePointer);
}
/** 讀入對象的頂點 */
void C3DSLoader::ReadVertices(t3DObject *pObject, tChunk *pPreChunk)
{
/** 讀入頂點的數目 */
pPreChunk->bytesRead += fread(&(pObject->numOfVerts), 1, 2, m_FilePointer);
/** 分配頂點的存儲空間,然后初始化結構體 */
pObject->pVerts = new Vector3 [pObject->numOfVerts];
memset(pObject->pVerts, 0, sizeof(Vector3) * pObject->numOfVerts);
/** 讀入頂點序列 */
pPreChunk->bytesRead += fread(pObject->pVerts, 1, pPreChunk->length - pPreChunk->bytesRead, m_FilePointer);
/** 遍歷所有的頂點將Y軸和Z軸交換,然后將Z軸反向 */
for(int i = 0; i < pObject->numOfVerts; i++)
{
/** 保存Y軸的值 */
float fTempY = pObject->pVerts[i].y;
/** 設置Y軸的值等于Z軸的值 */
pObject->pVerts[i].y = pObject->pVerts[i].z;
/** 設置Z軸的值等于-Y軸的值 */
pObject->pVerts[i].z = -fTempY;
}
}
/** 讀入對象的材質名稱 */
void C3DSLoader::ReadObjMat(t3DModel *pModel, t3DObject *pObject, tChunk *pPreChunk)
{
char strMaterial[255] = {0}; /**< 用來保存對象的材質名稱 */
int buffer[50000] = {0}; /**< 用來讀入不需要的數據 */
/** 讀入賦予當前對象的材質名稱 */
pPreChunk->bytesRead += GetString(strMaterial);
/** 遍歷所有的紋理 */
for(int i = 0; i < pModel->numOfMaterials; i++)
{
/** 如果讀入的紋理與當前的紋理名稱匹配 */
if(strcmp(strMaterial, pModel->pMaterials[i].strName) == 0)
{
/** 設置材質ID */
pObject->materialID = i;
/** 判斷是否是紋理映射 */
if(strlen(pModel->pMaterials[i].strFile) > 0) {
/** 設置對象的紋理映射標志 */
pObject->bHasTexture = true;
}
break;
}
else
{
/** 如果該對象沒有材質,則設置ID為-1 */
pObject->materialID = -1;
}
}
pPreChunk->bytesRead += fread(buffer, 1, pPreChunk->length - pPreChunk->bytesRead, m_FilePointer);
}
/** 計算對象的法向量 */
void C3DSLoader::ComputeNormals(t3DModel *pModel)
{
Vector3 vVector1, vVector2, vNormal, vPoly[3];
/** 如果模型中沒有對象,則返回 */
if(pModel->numOfObjects <= 0)
return;
/** 遍歷模型中所有的對象 */
for(int index = 0; index < pModel->numOfObjects; index++)
{
/** 獲得當前的對象 */
t3DObject *pObject = &(pModel->pObject[index]);
/** 分配需要的存儲空間 */
Vector3 *pNormals = new Vector3 [pObject->numOfFaces];
Vector3 *pTempNormals = new Vector3 [pObject->numOfFaces];
pObject->pNormals = new Vector3 [pObject->numOfVerts];
/** 遍歷對象的所有面 */
for(int i=0; i < pObject->numOfFaces; i++)
{ vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];
/** 計算面的法向量 */
vVector1 = vPoly[0] - vPoly[2]; /**< 獲得多邊形的矢量 */
vVector2 = vPoly[2] - vPoly[1]; /**< 獲得多邊形的第二個矢量 */
vNormal = vVector1.crossProduct(vVector2); /**< 計算兩個矢量的叉積 */
pTempNormals[i] = vNormal;
vNormal = vNormal.normalize(); /**< 規一化叉積 */
pNormals[i] = vNormal; /**< 將法向量添加到法向量列表中 */
}
/** 計算頂點法向量 */
Vector3 vSum(0.0,0.0,0.0);
Vector3 vZero = vSum;
int shared=0;
/** 遍歷所有的頂點 */
for (i = 0; i < pObject->numOfVerts; i++)
{ for (int j = 0; j < pObject->numOfFaces; j++) /**< 遍歷所有的三角形面 */
{ /**< 判斷該點是否與其它的面共享 */
if (pObject->pFaces[j].vertIndex[0] == i ||
pObject->pFaces[j].vertIndex[1] == i ||
pObject->pFaces[j].vertIndex[2] == i)
{
vSum = vSum + pTempNormals[j];
shared++;
}
}
pObject->pNormals[i] = vSum / float(-shared);
/** 規一化頂點法向 */
pObject->pNormals[i] = pObject->pNormals[i].normalize();
vSum = vZero;
shared = 0;
}
/** 釋放存儲空間,開始下一個對象 */
delete [] pTempNormals;
delete [] pNormals;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -