📄 3dsfile.cpp
字号:
INT numb_faces = ReadInt();
Mesh.m_vFaces.resize(numb_faces);
for (INT nNum=0;nNum<numb_faces;nNum++)
{
Mesh.m_vFaces[nNum].m_usIndices[0] = ReadInt();
Mesh.m_vFaces[nNum].m_usIndices[1] = ReadInt();
Mesh.m_vFaces[nNum].m_usIndices[2] = ReadInt();
Mesh.m_vFaces[nNum].m_usInfo = ReadInt();
teller += 8L;
}
while ( bEnd == FALSE )
{
UINT temp_int = ReadInt();
switch( temp_int )
{
case TRI_FACEMATL:
{
_3DSUseMat Mat;
teller += ReadMeshUseMatChunk(Mat);
Mesh.m_vUseMaterials.push_back(Mat);
}
break;
case TRI_SMOOTH:
teller += ReadUnknownChunk(); break;
}
if ( teller == temp_pointer )
bEnd = TRUE;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadMeshUseMatChunk(_3DSUseMat &Mat)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
DWORD teller = 8L;// id:2 + pointer:4 + number:2
UINT face_indices = 0;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
teller += ReadName(Mat.m_strName,256);
face_indices = ReadInt();
Mat.m_vFaceIndices.resize(face_indices);
for( UINT nNum = 0; nNum < Mat.m_vFaceIndices.size(); ++nNum)
{
Mat.m_vFaceIndices[nNum] = ReadInt();
teller += 2L;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadMeshTexCoordChunk(_3DSTriMesh &Mesh)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
DWORD teller = 8L;// id:2 + pointer:4 + number:2
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
Mesh.m_vTexCoords.resize(ReadInt());
for( UINT nNum = 0; nNum < Mesh.m_vTexCoords.size(); ++nNum)
{
Mesh.m_vTexCoords[nNum].u = ReadFloat();
Mesh.m_vTexCoords[nNum].v = ReadFloat();
teller += 8L;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
VOID _3DS::DrawModel(LPDIRECT3DVERTEXBUFFER8 vb)
{
INT numOfModel = 0;
INT numOfObject = 0;
INT numOfMesh = 0;
INT numOfUseMat = 0;
INT numOfFace = 0;
BYTE bHasTex = TRUE;
for (numOfMesh = 0; numOfMesh < m_3DSFile.m_vModels.size(); ++numOfMesh)
{
_3DSModel & Model = m_3DSFile.m_vModels[numOfMesh];
for ( numOfObject = 0; numOfObject < Model.m_vObjects.size(); ++numOfObject)
{
_3DSObject & Object = Model.m_vObjects[numOfObject];
for ( numOfMesh = 0; numOfMesh < Object.m_vTriMeshs.size(); ++numOfMesh)
{
_3DSTriMesh & Mesh = Object.m_vTriMeshs[numOfMesh];
if ( Mesh.m_vTexCoords.size() == 0 ) bHasTex = FALSE;
for ( numOfUseMat = 0; numOfUseMat< Mesh.m_vUseMaterials.size();++numOfUseMat)
{
_3DSUseMat & UseMat = Mesh.m_vUseMaterials[numOfUseMat];
if ( (INT)UseMat.m_usMatIdx < 0 )
{
if ( UseMat.m_vFaceIndices.size() < 1 )
continue;
D3DMATERIAL8 mat = {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f}};
m_pD3DDevice->SetMaterial(&mat);
m_pD3DDevice->SetTexture(0,NULL);
}
else
{
m_pD3DDevice->SetMaterial(&Model.m_vUseMaterials[UseMat.m_usMatIdx]);
m_pD3DDevice->SetTexture(0,Model.m_vTextures[UseMat.m_usMatIdx]);
}
m_pD3DDevice->SetStreamSource(0, vb, sizeof(D3DVERTEX));
m_pD3DDevice->SetVertexShader(D3DVERTEX::D3DFVF_D3DVERTEX);
D3DVERTEX *Ptr;
if (FAILED(vb->Lock(0, 0, (BYTE **)&Ptr, 0)))
return;
LONG FLUSH = 0;
for (numOfFace = 0; numOfFace < UseMat.m_vFaceIndices.size(); ++numOfFace)
{
_3DSFace &Face = Mesh.m_vFaces[UseMat.m_vFaceIndices[numOfFace]];
for (INT iVert = 0; iVert < 3; iVert++)
{
_3DSVert & v = Mesh.m_vVertices[Face.m_usIndices[iVert]];
if ( bHasTex == TRUE )
{
_3DSTexCoord & tex = Mesh.m_vTexCoords[Face.m_usIndices[iVert]];
Ptr[0] = D3DVERTEX(D3DXVECTOR3(v.vPos.x,v.vPos.y,v.vPos.z),
D3DXVECTOR3(v.vNormal.x,v.vNormal.y,v.vNormal.z),
tex.u,tex.v);
}
else
{
Ptr[0] = D3DVERTEX(D3DXVECTOR3(v.vPos.x,v.vPos.y,v.vPos.z),
D3DXVECTOR3(v.vNormal.x,v.vNormal.y,v.vNormal.z),
0,0);
}
Ptr++;
}
FLUSH++;
if ( FLUSH >= MAX_DRAW_FACES )
{
vb->Unlock();
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, FLUSH);
if (FAILED(vb->Lock(0, 0, (BYTE **)&Ptr, 0)))
return;
FLUSH = 0;
}
}
vb->Unlock();
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, FLUSH);
}
}
}
}
}
VOID _3DS::Parse3DSFile()
{
INT numOfModel = 0;
INT numOfObject = 0;
INT numOfMaterial = 0;
INT numOfUseMat = 0;
INT numOfTriMesh = 0;
INT numOfFace = 0;
TCHAR strPath[MAX_PATH] = {0};
for ( numOfModel = 0; numOfModel < m_3DSFile.m_vModels.size(); ++numOfModel)
{
_3DSModel & Model = m_3DSFile.m_vModels[numOfModel];
if ( Model.m_vMaterials.size() == 0 )
{
_3DSMaterial DefaultMaterial;
_tcscpy(DefaultMaterial.m_strName,"%NoName%");
Model.m_vMaterials.push_back(DefaultMaterial);
Model.m_vUseMaterials.resize(1);
Model.m_vTextures.resize(1);
}
else
{
Model.m_vUseMaterials.resize(Model.m_vMaterials.size());
Model.m_vTextures.resize(Model.m_vMaterials.size());
}
for ( numOfMaterial = 0; numOfMaterial < Model.m_vMaterials.size();++numOfMaterial)
{
_3DSMaterial & Material = Model.m_vMaterials[numOfMaterial];
wsprintf(strPath,"%s%s",m_strFilePath,Model.m_vMaterials[numOfMaterial].m_strDiffuseTexture);
if ( FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, strPath, &Model.m_vTextures[numOfMaterial])))
Model.m_vTextures[numOfMaterial] = NULL;
Model.m_vUseMaterials[numOfMaterial].Diffuse.r = Material.m_fDiffuseclr.r;
Model.m_vUseMaterials[numOfMaterial].Diffuse.g = Material.m_fDiffuseclr.g;
Model.m_vUseMaterials[numOfMaterial].Diffuse.b = Material.m_fDiffuseclr.b;
Model.m_vUseMaterials[numOfMaterial].Diffuse.a = Material.m_fTransparency;
Model.m_vUseMaterials[numOfMaterial].Ambient.r = Material.m_fAmbientclr.r;
Model.m_vUseMaterials[numOfMaterial].Ambient.g = Material.m_fAmbientclr.g;
Model.m_vUseMaterials[numOfMaterial].Ambient.b = Material.m_fAmbientclr.b;
Model.m_vUseMaterials[numOfMaterial].Ambient.a = 1.0f;
Model.m_vUseMaterials[numOfMaterial].Specular.r = Material.m_fSpecularclr.r;
Model.m_vUseMaterials[numOfMaterial].Specular.g = Material.m_fSpecularclr.g;
Model.m_vUseMaterials[numOfMaterial].Specular.b = Material.m_fSpecularclr.b;
Model.m_vUseMaterials[numOfMaterial].Specular.a = 1.0f;
Model.m_vUseMaterials[numOfMaterial].Emissive.r = 0;
Model.m_vUseMaterials[numOfMaterial].Emissive.g = 0;
Model.m_vUseMaterials[numOfMaterial].Emissive.b = 0;
Model.m_vUseMaterials[numOfMaterial].Emissive.a = 0;
Model.m_vUseMaterials[numOfMaterial].Power = 100.0f - Material.m_fShininess*100.0f;
for ( numOfObject = 0; numOfObject < Model.m_vObjects.size(); ++numOfObject)
{
_3DSObject & Object = Model.m_vObjects[numOfObject];
for ( numOfTriMesh = 0; numOfTriMesh < Object.m_vTriMeshs.size(); ++numOfTriMesh)
{
_3DSTriMesh & Mesh = Object.m_vTriMeshs[numOfTriMesh];
if ( Mesh.m_vUseMaterials.size() == 0)
{
_3DSUseMat DefaultUseMat;
_tcscpy(DefaultUseMat.m_strName,"%NoName%");
DefaultUseMat.m_vFaceIndices.resize(Mesh.m_vFaces.size());
for ( numOfFace = 0; numOfFace < Mesh.m_vFaces.size(); ++numOfFace)
{
DefaultUseMat.m_vFaceIndices[numOfFace] = numOfFace;
}
Mesh.m_vUseMaterials.push_back(DefaultUseMat);
}
BYTE * bFaceHasMat = new BYTE[Mesh.m_vFaces.size()];
for ( numOfUseMat = 0; numOfUseMat < Mesh.m_vUseMaterials.size(); ++numOfUseMat)
{
_3DSUseMat & UseMat = Mesh.m_vUseMaterials[numOfUseMat];
if ( _tcscmp( UseMat.m_strName,Material.m_strName) == 0)
UseMat.m_usMatIdx = numOfMaterial;
for ( INT i = 0; i<UseMat.m_vFaceIndices.size(); ++i)
{
bFaceHasMat[UseMat.m_vFaceIndices[i]] = TRUE;
}
}
// 添加附加Mat.
_3DSUseMat ExtraMat;
ExtraMat.m_usMatIdx = -1;
for ( numOfFace = 0; numOfFace < Mesh.m_vFaces.size(); ++numOfFace)
{
if(bFaceHasMat[numOfFace] != TRUE)
{
ExtraMat.m_vFaceIndices.push_back(numOfFace);
}
}
if ( ExtraMat.m_vFaceIndices.size() != 0 )
Mesh.m_vUseMaterials.push_back(ExtraMat);
SAFE_DELETE_ARRAY(bFaceHasMat);
}
}
}
}
}
VOID _3DS::CalculateFaceNormals()
{
INT numOfModel = 0;
INT numOfObject = 0;
INT numOfTriMesh = 0;
INT numOfFace = 0;
INT numOfVert = 0;
for ( numOfModel = 0; numOfModel < m_3DSFile.m_vModels.size(); ++numOfModel)
{
_3DSModel & Model = m_3DSFile.m_vModels[numOfModel];
for ( numOfObject = 0; numOfObject < Model.m_vObjects.size(); ++numOfObject)
{
_3DSObject & Object = Model.m_vObjects[numOfObject];
for ( numOfTriMesh = 0; numOfTriMesh < Object.m_vTriMeshs.size(); ++numOfTriMesh)
{
_3DSTriMesh & Mesh = Object.m_vTriMeshs[numOfTriMesh];
for ( numOfFace = 0; numOfFace < Mesh.m_vFaces.size(); ++numOfFace)
{
_3DSFace & Face = Mesh.m_vFaces[numOfFace];
_3DSVect & va = Mesh.m_vVertices[Face.m_usIndices[0]].vPos;
_3DSVect & vb = Mesh.m_vVertices[Face.m_usIndices[1]].vPos;
_3DSVect & vc = Mesh.m_vVertices[Face.m_usIndices[2]].vPos;
D3DXVECTOR3 vA = D3DXVECTOR3(va.x,va.y,va.z);
D3DXVECTOR3 vB = D3DXVECTOR3(vb.x,vb.y,vb.z);
D3DXVECTOR3 vC = D3DXVECTOR3(vc.x,vc.y,vc.z);
D3DXVECTOR3 vAC,vAB,vNormal;
D3DXVec3Subtract(&vAC,&vA,&vC);
D3DXVec3Subtract(&vAB,&vB,&vA);
D3DXVec3Cross(&vNormal, &vAC, &vAB);
D3DXVec3Normalize(&vNormal,&vNormal);
Face.m_vecNormal.x = vNormal.x;
Face.m_vecNormal.y = vNormal.y;
Face.m_vecNormal.z = vNormal.z;
}
for ( numOfVert = 0; numOfVert < Mesh.m_vVertices.size(); ++numOfVert)
{
INT VertShare = 0;
_3DSVert & Vert = Mesh.m_vVertices[numOfVert];
D3DXVECTOR3 vNormal = D3DXVECTOR3(0,0,0);
for ( numOfFace = 0; numOfFace < Mesh.m_vFaces.size(); ++numOfFace)
{
_3DSFace & Face = Mesh.m_vFaces[numOfFace];
if ( Face.m_usIndices[0] == numOfVert || Face.m_usIndices[1] == numOfVert || Face.m_usIndices[2] == numOfVert )
{
vNormal.x += Face.m_vecNormal.x;
vNormal.y += Face.m_vecNormal.y;
vNormal.z += Face.m_vecNormal.z;
VertShare ++;
}
}
vNormal.x /= VertShare;
vNormal.y /= VertShare;
vNormal.z /= VertShare;
D3DXVec3Normalize(&vNormal,&vNormal);
Vert.vNormal.x = vNormal.x;
Vert.vNormal.y = vNormal.y;
Vert.vNormal.z = vNormal.z;
}
}
}
}
}
VOID _3DS::ArrangeVertex()
{
INT numOfModel = 0;
INT numOfObject = 0;
INT numOfTriMesh = 0;
INT numOfFace = 0;
INT numOfVert = 0;
INT numOfTexCoord = 0;
for ( numOfModel = 0; numOfModel < m_3DSFile.m_vModels.size(); ++numOfModel)
{
_3DSModel & Model = m_3DSFile.m_vModels[numOfModel];
for ( numOfObject = 0; numOfObject < Model.m_vObjects.size(); ++numOfObject)
{
_3DSObject & Object = Model.m_vObjects[numOfObject];
for ( numOfTriMesh = 0; numOfTriMesh < Object.m_vTriMeshs.size(); ++numOfTriMesh)
{
_3DSTriMesh & Mesh = Object.m_vTriMeshs[numOfTriMesh];
for ( numOfVert = 0; numOfVert < Mesh.m_vVertices.size(); ++numOfVert)
{
_3DSVert & vert = Mesh.m_vVertices[numOfVert];
std::swap(vert.vPos.y,vert.vPos.z);
}
for ( numOfTexCoord = 0; numOfTexCoord <Mesh.m_vTexCoords.size(); ++numOfTexCoord)
{
_3DSTexCoord & tex = Mesh.m_vTexCoords[numOfTexCoord];
tex.v = -tex.v;
}
for ( numOfFace = 0; numOfFace < Mesh.m_vFaces.size(); ++numOfFace)
{
_3DSFace & face = Mesh.m_vFaces[numOfFace];
std::swap(face.m_usIndices[1],face.m_usIndices[2]);
}
}
}
}
}
VOID _3DS::CalculateBoundingMesh()
{
INT numOfModel = 0;
INT numOfObject = 0;
INT numOfTriMesh = 0;
INT numOfFace = 0;
INT numOfVert = 0;
INT numOfTexCoord = 0;
for ( numOfModel = 0; numOfModel < m_3DSFile.m_vModels.size(); ++numOfModel)
{
_3DSModel & Model = m_3DSFile.m_vModels[numOfModel];
for ( numOfObject = 0; numOfObject < Model.m_vObjects.size(); ++numOfObject)
{
_3DSObject & Object = Model.m_vObjects[numOfObject];
for ( numOfTriMesh = 0; numOfTriMesh < Object.m_vTriMeshs.size(); ++numOfTriMesh)
{
_3DSTriMesh & Mesh = Object.m_vTriMeshs[numOfTriMesh];
if ( Mesh.m_vVertices.size() != 0)
{
D3DXComputeBoundingBox((PVOID)Mesh.m_vVertices.begin(),Mesh.m_vVertices.size(),
D3DVERTEX::D3DFVF_D3DVERTEX,&Mesh.m_vMin,&Mesh.m_vMax);
D3DXComputeBoundingSphere((PVOID)Mesh.m_vVertices.begin(),Mesh.m_vVertices.size(),
D3DVERTEX::D3DFVF_D3DVERTEX,&D3DXVECTOR3(0,0,0),&Mesh.m_fRadius);
m_vMin.x = min(m_vMin.x, Mesh.m_vMin.x);
m_vMin.y = min(m_vMin.y, Mesh.m_vMin.y);
m_vMin.z = min(m_vMin.z, Mesh.m_vMin.z);
m_vMax.x = max(m_vMax.x, Mesh.m_vMax.x);
m_vMax.y = max(m_vMax.y, Mesh.m_vMax.y);
m_vMax.z = max(m_vMax.z, Mesh.m_vMax.z);
m_fRadius = max(m_fRadius, Mesh.m_fRadius);
}
}
}
}
}
VOID _3DS::Read3DSFile(LPDIRECT3DDEVICE8 device,TCHAR * strFileName,TCHAR * strFilePath)
{
m_fpBin3ds = NULL;
m_pD3DDevice = device;
if ( strFileName == NULL )
return;
m_fpBin3ds = _tfopen(strFileName,"rb");
if ( m_fpBin3ds == NULL )
return;
fseek(m_fpBin3ds,28L,SEEK_SET);
m_3DSFile.Version = ReadChar();
if ( m_3DSFile.Version < 3 )
return;
ChangeChunkPointer(0);
ReadPrimaryChunk();
fclose(m_fpBin3ds);
_tcscpy(m_strFilePath,strFilePath);
ArrangeVertex();
CalculateFaceNormals();
Parse3DSFile();
CalculateBoundingMesh();
}
DWORD _3DS::ReadLightChunk(_3DSLight & Light)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
DWORD teller = 6L + 12L;
BYTE bEnd = FALSE;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
Light.m_vPos.x = ReadFloat();
Light.m_vPos.y = ReadFloat();
Light.m_vPos.z = ReadFloat();
while ( bEnd == FALSE )
{
switch( ReadInt() )
{
teller += ReadChunkPointer();
Light.m_Diffuseclr.r = ReadFloat();
Light.m_Diffuseclr.g = ReadFloat();
Light.m_Diffuseclr.b = ReadFloat();
break;
case COL_TRU :
teller += ReadChunkPointer();
Light.m_Diffuseclr.r = (FLOAT) ReadChar() / 255.0f;
Light.m_Diffuseclr.g = (FLOAT) ReadChar() / 255.0f;
Light.m_Diffuseclr.b = (FLOAT) ReadChar() / 255.0f;
break;
case LIT_SPOT:
teller += ReadChunkPointer();
Light.m_vSpotlightDir.x = ReadFloat();
Light.m_vSpotlightDir.y = ReadFloat();
Light.m_vSpotlightDir.z = ReadFloat();
Light.m_fSpot = ReadFloat();
Light.m_fAngle = ReadFloat();
break;
case LIT_OFF:
ReadBooleanChunk(&Light.m_bOn);
break;
default:
ReadUnknownChunk();
break;
}
if( teller == temp_pointer)
bEnd = TRUE;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -