📄 3dsfile.cpp
字号:
#include "HEADERS.H"
#include "3DSFILE.H"
USING NAMESPACE CGE::MODEL::_3DSFILE;
#define MAX_DRAW_FACES 512
_3DS::_3DS()
{
m_fpBin3ds = 0;
m_strFilePath[0] = '\0';
m_vMin.x = m_vMin.y = m_vMin.z = 0;
m_vMax.x = m_vMax.y = m_vMax.z = 0;
m_fRadius = 0.0f;
}
_3DS::~_3DS()
{
}
BYTE _3DS::ReadChar()
{
return (fgetc(m_fpBin3ds));
}
FLOAT _3DS::ReadFloat()
{
FLOAT fVal;
fread(&fVal,1,sizeof(FLOAT),m_fpBin3ds);
return fVal;
}
UINT _3DS::ReadInt()
{
UINT temp = ReadChar();
return ( temp | (ReadChar () << 8));
}
DWORD _3DS::ReadChunkPointer()
{
DWORD temp1,temp2;
temp1=ReadInt ();
temp2=ReadInt ();
return (temp1+( temp2 << 16 ));
}
DWORD _3DS::ReadLong()
{
DWORD temp1,temp2;
temp1=ReadInt ();
temp2=ReadInt ();
return (temp1+(temp2*0x10000L));
}
VOID _3DS::ChangeChunkPointer(DWORD temp_pointer)
{
fseek (m_fpBin3ds,temp_pointer,SEEK_SET);
}
DWORD _3DS::GetChunkPointer()
{
return (ftell(m_fpBin3ds)-2); // compensate for the already read Marker
}
BOOL _3DS::ReadPrimaryChunk()
{
DWORD current_pointer = 0;
DWORD teller = 2L;
while ( ReadInt() == MAIN3DS )
{
current_pointer = GetChunkPointer();
teller += ReadMainChunk();
ChangeChunkPointer(current_pointer+teller);
}
return TRUE;
}
DWORD _3DS::ReadMainChunk()
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
BOOL bEnd = FALSE;
DWORD teller = 6L; // id:2 + pointer:4
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
while ( bEnd == FALSE )
{
switch( ReadInt() )
{
case EDIT3DS:
{
_3DSModel Model;
teller += ReadEditChunk(Model);
m_3DSFile.m_vModels.push_back(Model);
break;
}
case KEYFRAME3DS:
{
_3DSKeyFrame KeyFrame;
teller += ReadKeyFrameChunk(KeyFrame);
m_3DSFile.m_vKeyFrames.push_back(KeyFrame);
break;
}
default:
teller += ReadUnknownChunk();break;
break;
}
if ( teller == temp_pointer )
bEnd = TRUE;
}
ChangeChunkPointer(current_pointer+teller);
return (temp_pointer);
}
DWORD _3DS::ReadEditChunk(_3DSModel & Model)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
DWORD teller = 6L;
BOOL bEnd = FALSE;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
while ( bEnd == FALSE )
{
switch( ReadInt() )
{
case EDIT_BACKGR:
Model.m_bHasBackgr = TRUE;
teller += ReadColorChunk(Model.m_fBackgrclr);
break;
case EDIT_AMBIENT:
Model.m_bHasAmbient = TRUE;
teller += ReadColorChunk(Model.m_fAmbientclr);
break;
case EDIT_OBJECT:
{
_3DSObject Obj;
teller += ReadObjectChunk(Obj);
Model.m_vObjects.push_back(Obj);
break;
}
case EDIT_MATERIAL:
{
_3DSMaterial Mat;
teller += ReadMaterialChunk(Mat);
Model.m_vMaterials.push_back(Mat);
break;
}
default:
teller += ReadUnknownChunk();
break;
}
if ( teller == temp_pointer )
bEnd = TRUE;
}
ChangeChunkPointer( current_pointer + temp_pointer );
return (temp_pointer);
}
DWORD _3DS::ReadKeyFrameChunk(_3DSKeyFrame & KeyFrame)
{
BYTE bEnd=FALSE;
DWORD current_pointer;
DWORD temp_pointer;
DWORD teller=6L;
current_pointer=GetChunkPointer ();
temp_pointer =ReadChunkPointer ();
while (bEnd==FALSE)
{
switch (ReadInt())
{
case KEYF_UNKNWN01:
teller+=ReadUnknownChunk();
break;
case KEYF_UNKNWN02:
teller+=ReadUnknownChunk();
break;
case KEYF_FRAMES:
teller += ReadChunkPointer();
KeyFrame.m_dwStart = ReadLong();
KeyFrame.m_dwEnd = ReadLong();
break;
case KEYF_OBJDES:
teller+=ReadUnknownChunk();
break;
case EDIT_VIEW1:
teller+=ReadUnknownChunk();
break;
default:
ReadUnknownChunk();
break;
}
if (teller=temp_pointer)
bEnd=TRUE;
}
ChangeChunkPointer (current_pointer+temp_pointer);
// move to the new chunk position
return (temp_pointer);
}
DWORD _3DS::ReadUnknownChunk()
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
current_pointer = GetChunkPointer ();
temp_pointer = ReadChunkPointer ();
ChangeChunkPointer(current_pointer+temp_pointer);
// move to the new chunk position
return (temp_pointer);
}
DWORD _3DS::ReadMaterialChunk(_3DSMaterial & Mat)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
UINT temp_int = 0;
DWORD teller = 6L;
BOOL bEnd = FALSE;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
while ( bEnd == FALSE )
{
temp_int = ReadInt();
switch( temp_int )
{
case MAT_NAME01:
teller += ReadNameChunk(Mat.m_strName,256);
break;
case MAT_AMBIENT:
teller += ReadColorChunk(Mat.m_fAmbientclr);
break;
case MAT_DIFFUSE:
teller += ReadColorChunk(Mat.m_fDiffuseclr);
break;
case MAT_SPECULAR:
teller += ReadColorChunk(Mat.m_fSpecularclr);
break;
case MAT_SHININESS:
teller += ReadMatDefChunk(Mat.m_fShininess);
break;
case MAT_TRANSPARENCY:
teller += ReadMatDefChunk(Mat.m_fTransparency);
break;
case MAT_TEXMAP:
teller += ReadMaterialChunk(Mat);
break;
case MAT_TEXFILE:
teller += ReadNameChunk(Mat.m_strDiffuseTexture,256);
break;
default:
teller += ReadUnknownChunk();
break;
}
if ( teller == temp_pointer )
bEnd = TRUE;
}
ChangeChunkPointer( current_pointer+temp_pointer );
return (temp_pointer);
}
DWORD _3DS::ReadName( TCHAR * strName, WORD buffSize)
{
TCHAR character = 0;
DWORD teller = 0;
_tcscpy(strName,"%NoName%");
character = ReadChar();
if ( character == 0 ) return (1);
strName[teller] = character;
++teller;
do
{
character=ReadChar();
strName[teller]=character;
teller++;
}
while (character!=0);
// If the length of the string greater than bufSize, cut it
if (teller < buffSize)
strName[teller-1] = 0;
else
strName[buffSize - 1] = 0;
return (teller);
}
DWORD _3DS::ReadNameChunk(TCHAR *strName,WORD buffSize)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
ReadName(strName,buffSize);
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadObjectChunk(_3DSObject & Obj)
{
BOOL bEnd = FALSE;
DWORD teller = 6L;
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
UINT temp_int = 0;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
teller += ReadName(Obj.m_strName,256);
while( bEnd == FALSE )
{
temp_int = ReadInt();
switch(temp_int)
{
case OBJ_TRIMESH:
{
_3DSTriMesh TriMesh;
teller += ReadTriMeshChunk(TriMesh);
Obj.m_vTriMeshs.push_back(TriMesh);
break;
}
case OBJ_LIGHT:
{
_3DSLight Light;
ReadLightChunk(Light);
break;
}
default:
teller += ReadUnknownChunk();
break;
}
if ( teller == temp_pointer )
{
bEnd = TRUE;
}
}
ChangeChunkPointer(current_pointer + temp_pointer );
return (temp_pointer);
}
DWORD _3DS::ReadColorChunk(_3DSClr & clr)
{
DWORD current_pointer;
DWORD temp_pointer;
DWORD teller = 6L; // id:2 + pointer:4
current_pointer=GetChunkPointer ();
temp_pointer =ReadChunkPointer ();
switch (ReadInt())
{
case COL_RGB :
teller += ReadChunkPointer();
clr.r = ReadFloat();
clr.g = ReadFloat();
clr.b = ReadFloat();
break;
case COL_TRU :
teller += ReadChunkPointer();
clr.r = (FLOAT) ReadChar() / 255.0f;
clr.g = (FLOAT) ReadChar() / 255.0f;
clr.b = (FLOAT) ReadChar() / 255.0f;
break;
default:
ReadUnknownChunk();
break;
}
ChangeChunkPointer (current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadMatDefChunk(FLOAT &value)
{
DWORD current_pointer;
DWORD temp_pointer;
BOOL bEnd = FALSE;
UINT temp_int = 0;
DWORD teller = 6L;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
while( bEnd == FALSE )
{
temp_int = ReadInt();
if ( temp_int == 0x0030 )
{
teller += ReadChunkPointer();
value = (FLOAT)(100 - ReadInt()) / 100.0f;
}
if ( teller == temp_pointer )
bEnd = TRUE;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadBooleanChunk(BYTE *boolean)
{
DWORD current_pointer;
DWORD temp_pointer;
current_pointer=GetChunkPointer ();
temp_pointer =ReadChunkPointer ();
*boolean=ReadChar ();
ChangeChunkPointer (current_pointer+temp_pointer); // move to the new chunk position
return (temp_pointer);
}
DWORD _3DS::ReadTriMeshChunk(_3DSTriMesh &Mesh)
{
BYTE bEnd=FALSE,boolean=TRUE;
UINT temp_int;
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
DWORD teller=6L; // 2 id + 4 pointer
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
while (bEnd==FALSE)
{
temp_int=ReadInt();
switch (temp_int)
{
case TRI_VERTEXL:
teller += ReadMeshVertsChunk(Mesh);
break;
case TRI_VERTEXOP:
teller += ReadUnknownChunk();
break;
case TRI_FACEL:
teller += ReadMeshFacesChunk(Mesh);
break;
case TRI_TEXCOORD:
teller += ReadMeshTexCoordChunk(Mesh);
break;
case TRI_LOCAL:
teller += ReadUnknownChunk();
break;
case TRI_VISIBLE:
teller += ReadBooleanChunk(&Mesh.m_bVisible);
break;
default:
ReadUnknownChunk();
break;
}
if (teller == temp_pointer)
bEnd=TRUE;
}
ChangeChunkPointer (current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadMeshVertsChunk(_3DSTriMesh &Mesh)
{
DWORD current_pointer = 0;
DWORD temp_pointer = 0;
UINT number_vert = 0;
DWORD teller = 8L; // id:2 + pointer:4 + number:2
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
number_vert = ReadInt();
Mesh.m_vVertices.resize(number_vert);
for ( UINT nNum = 0; nNum < Mesh.m_vVertices.size(); ++nNum )
{
Mesh.m_vVertices[nNum].vPos.x = ReadFloat();
Mesh.m_vVertices[nNum].vPos.y = ReadFloat();
Mesh.m_vVertices[nNum].vPos.z = ReadFloat();
teller += 12L;
}
ChangeChunkPointer(current_pointer+temp_pointer);
return (temp_pointer);
}
DWORD _3DS::ReadMeshFacesChunk(_3DSTriMesh &Mesh)
{
DWORD current_pointer;
DWORD temp_pointer;
DWORD teller = 8L; // id:2 + pointer:4 + number:2
BYTE bEnd = FALSE;
current_pointer = GetChunkPointer();
temp_pointer = ReadChunkPointer();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -