⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dsfile.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -