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

📄 bspmanager.cpp

📁 BSP地形系统和光照贴图的技术详解
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Bsp.cpp: implementation of the CBsp class.
//
//////////////////////////////////////////////////////////////////////

#include "BspManager.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int			g_count = 0;

CBspManager::CBspManager()
{
	m_nBrushCount			= 0;
	m_nPortalCnt			= 0;
	m_nTexCnt				= 0;
	m_nFaceCount			= 0;
	m_ppPortals				= NULL;
	m_pBrushs				= NULL;
	m_pCSGBrushs			= NULL;
	m_pFaceRoot				= NULL;
	m_pNewFaceRoot			= NULL;
	m_pBspRoot				= NULL;
	m_pRenderNode			= NULL;
	m_pTXData				= NULL;
	m_pLight				= NULL;

	m_vMax					= D3DXVECTOR3( -BSP_BOGUS, -BSP_BOGUS, -BSP_BOGUS );
	m_vMin					= D3DXVECTOR3( BSP_BOGUS, BSP_BOGUS, BSP_BOGUS );

	m_ppLightMap			= NULL;
	m_pStaticThing			= NULL;
	m_pDynamicThing			= NULL;

	m_pDynamicLight			= NULL;
}

CBspManager::~CBspManager()
{
	if( m_pDynamicLight )
		delete m_pDynamicLight;
	if( m_pDynamicThing )
		delete m_pDynamicThing;
	if( m_pStaticThing )
		delete m_pStaticThing;
	if( m_ppLightMap )
		delete[] m_ppLightMap;
	if( m_pLight )
		delete[] m_pLight;
	if( m_nTexCnt == 1 && m_nTexCnt != 0)
		delete m_pTXData;

	if( m_nTexCnt > 1 )
		delete[] m_pTXData;


	if( m_ppPortals )
		delete[] m_ppPortals;
	FreeAllPortals( m_pBspRoot );
	if( m_pBspRoot )
	{
		delete m_pBspRoot;
	}
	if( m_pBrushs )
	{
		if( m_nBrushCount > 1 )
		{
			delete[] m_pBrushs;
		}
		else if( m_nBrushCount > 0 )
		{
			delete m_pBrushs;
		}
	}

	CBrush * next = NULL, * curr = NULL;
	for( curr = m_pCSGBrushs ; curr ; curr = next )
	{
		next = curr->m_pNext;
		delete curr;
	}
	
//	m_pFaceRoot->Destroy();
}

BOOL CBspManager::ParseMaxFile(LPSTR szFileName)
{
	char tmpFileName[STR_MAX];
	FILE* fp;
	//LIGHT 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".tm");
		fp = fopen(tmpFileName, "r");
		SetLightInfo( fp );
		fclose( fp );
		
	//MAP 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".nfo");
		fp = fopen(tmpFileName, "r");
		SetMapInfo( fp );
		fclose( fp );

	//VERTEX 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".vtx");
		fp = fopen(tmpFileName, "r");
		SetVertices( fp );
		fclose( fp );
		
	//FACE INDEX 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".idx");
		fp = fopen(tmpFileName, "r");
		SetFaceIndex( fp );
		fclose( fp );
		
	//MATERIAL 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".mat");
		fp = fopen(tmpFileName, "r");
		SetMaterial( fp );
		fclose( fp );

	//TEXTURE VERTEX信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".vtt");
		fp = fopen(tmpFileName, "r");
		SetTextureVertices( fp );
		fclose( fp );

	//TVERTEX INDEX 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".idt");
		fp = fopen(tmpFileName, "r");
		SetTextureIndex( fp );
		fclose( fp );

	//TEXTURE NAME 信息
		strcpy(tmpFileName, szFileName);
		strcat(tmpFileName, ".txn");
		fp = fopen(tmpFileName, "r");
		SetTextureName( fp );
		fclose( fp );

	return TRUE;
}

CBrush* CBspManager::GetBrushFromName( LPSTR szName )
{
	for( int i = 0; i < m_nBrushCount ; i++ )
	{
		if( !strcmp( m_pBrushs[i].m_szName, szName ) )
			return &m_pBrushs[i];
	}
	return NULL;
}

BOOL CBspManager::SetMaterial(FILE *fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	int num = 0;
	GetToken( fp, lpszFormer );
	if( strcmp( lpszFormer, "MATERIAL") )
		return FALSE;

	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(lpszFormer, "TEXTURE"))
		{
			num++;
		}
	}

	if( num <= 0 )
		return FALSE;

	m_nTexCnt = num;

	m_pTXData = new TEXTUREDATA[num];
	num = 0;

	fseek( fp, 0, SEEK_SET );

	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(lpszFormer, "TEXTURE"))
		{
			strcpy( m_pTXData[num++].name, lpszOther );
		}
	}
	return TRUE;
}

void CBspManager::SetTextureName(FILE* fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	CBrush* pObj = NULL;
	int num = 0;
	float x, y, z;
	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(lpszFormer, "NAME"))
			pObj = GetBrushFromName(lpszOther);
		else if(!strcmp(lpszFormer, "TEXTURE"))
		{
			if(pObj)
			{
				pObj->m_nTexture = GetTextureIndex( lpszOther );
			}
		}
	}
}

int CBspManager::GetTextureIndex( LPSTR lpszName )
{
	if( m_nTexCnt <= 0 )
		return -1;

	for( int i = 0 ; i < m_nTexCnt ; i++ )
	{
		if( !strcmp( m_pTXData[i].name, lpszName ) )
			return i;
	}

	return -1;
}

void CBspManager::SetTexture( LPDIRECT3DDEVICE8 pd3dDevice )
{
	for( int i = 0 ; i < m_nTexCnt ; i++ )
	{
		D3DXCreateTextureFromFile( pd3dDevice, m_pTXData[i].name, &m_pTXData[i].texture );
/*		for( int j = 0 ; j < m_nBrushCount ; j++ )
		{
			if( !strcmp( m_pTXData[i].name, m_pBrushs[j].m_szName ) )
				m_pBrushs[j].m_nTexture = i;
		}*/
	}
}

void CBspManager::SetTextureVertices(FILE* fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	CBrush* pObj = NULL;
	int num = 0;
	float x, y, z;
	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(lpszFormer, "NAME"))
			pObj = GetBrushFromName(lpszOther);
		else if(!strcmp(lpszFormer, "COUNT"))
		{
			if(pObj)
			{
				pObj->m_nTCount = atoi(lpszOther);
				pObj->m_pTVtx = new D3DXVECTOR3[pObj->m_nTCount];
				num = 0;
			}
		}
		else if(pObj->m_nTCount > 0)
		{
			GetVertex(lpszOther, &x, &y, &z);
			pObj->m_pTVtx[num].x = x;
			pObj->m_pTVtx[num].y = y;
			//max中,由于 v上升增加,成为 1
			//D3D中,v下降增加 1
			pObj->m_pTVtx[num].z = 1.f - z;
			num++;
		}
	}
}

void CBspManager::SetTextureIndex(FILE *fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	CBrush* pObj = NULL;
	int num = 0;
	WORD first, second, third;

	GetToken( fp, lpszFormer );

	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(lpszFormer, "NAME"))
			pObj = GetBrushFromName(lpszOther);
		else if(!strcmp(lpszFormer, "COUNT"))
		{
			if(pObj)
			{
				pObj->m_nTFCount = atoi(lpszOther);
				pObj->m_pTIndex = new TRIANGLEINDEX[pObj->m_nTFCount];
				num = 0;
			}
		}
		else if(pObj->m_nTFCount > 0)
		{
			GetIndex(lpszOther, &first, &second, &third);
			pObj->m_pTIndex[num]._0 = first;
			pObj->m_pTIndex[num]._1 = second;
			pObj->m_pTIndex[num++]._2 = third;
		}

	}
}

void CBspManager::SetMapInfo(FILE* fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		if(!strcmp(lpszFormer, "OBJECTCOUNT"))
		{
			m_nBrushCount = atoi(lpszOther) - m_nStaticLight;
			m_pBrushs = new CBrush[m_nBrushCount];
			break;
		}
	}
}

void CBspManager::GetIndex(LPSTR lpszOther, WORD* first, WORD* second, WORD* third)
{
	char buffer[20];
	while(*lpszOther++ != START_BRACKET);

	for(int index=0, i=0;*lpszOther;lpszOther++)
	{
		if(*lpszOther == END_BRACKET)
			break;
		if(*lpszOther == COMMA)
		{
			buffer[i] = NULL;
			if(index == 0)
				*third = (WORD)(atoi(buffer))-1;
			else if(index == 1)
				*second = (WORD)(atoi(buffer))-1;
			i = 0;
			index++;
		}
		else
			buffer[i++] = *lpszOther;
	}
	buffer[i] = NULL;
	*first = (WORD)(atoi(buffer))-1;
}

void CBspManager::GetVertex(LPSTR lpszOther, float* x, float* y, float* z)
{
	char buffer[20];
	double buf = 0;
	while(*lpszOther++ != START_BRACKET);
	//Max的 yz坐标和 D3D的 yz必须变化.
	for(int index=0, i=0;*lpszOther;lpszOther++)
	{
		if(*lpszOther == END_BRACKET)
			break;
		if(*lpszOther == COMMA)
		{
			buffer[i] = NULL;
			if(index == 0)
				*x = (float)atof(buffer);
			else if(index == 1)
				*z = (float)atof(buffer);
			i = 0;
			index++;
		}
		else
			buffer[i++] = *lpszOther;
	}
	buffer[i] = NULL;
	*y = (float)atof(buffer);
}

// D3D的 Matrix				MAX的 Matrix
// _11 _12 _13 _14			_11 _13 _12 0
// _21 _22 _23 _24			_31 _33 _32 0
// _31 _32 _33 _34			_21 _23 _22 0
// _41 _42 _43 _44			_41 _43 _42 1
void CBspManager::GetTM(LPSTR lpszOther, D3DXMATRIX* pMat)
{
	char buffer[STR_MAX];
	int index = 0;
	while(*lpszOther++ != BLANK);
	while(1)
	{
		if(*lpszOther == END_BRACKET)
		{
			buffer[index] = *lpszOther;
			buffer[index+1] = NULL;
			GetVertex(buffer, &pMat->_11, &pMat->_12, &pMat->_13);
			index = 0;
			break;
		}
		buffer[index++] = *lpszOther++;
	}

	while(*lpszOther++ != BLANK);
	while(1)
	{
		if(*lpszOther == END_BRACKET)
		{
			buffer[index] = *lpszOther;
			buffer[index+1] = NULL;
			GetVertex(buffer, &pMat->_31, &pMat->_32, &pMat->_33);
			index = 0;
			break;
		}
		buffer[index++] = *lpszOther++;
	}

	while(*lpszOther++ != BLANK);
	while(1)
	{
		if(*lpszOther == END_BRACKET)
		{
			buffer[index] = *lpszOther;
			buffer[index+1] = NULL;
			GetVertex(buffer, &pMat->_21, &pMat->_22, &pMat->_23);
			index = 0;
			break;
		}
		buffer[index++] = *lpszOther++;
	}

	while(*lpszOther++ != BLANK);
	while(1)
	{
		if(*lpszOther == END_BRACKET)
		{
			buffer[index] = *lpszOther;
			buffer[index+1] = NULL;
			GetVertex(buffer, &pMat->_41, &pMat->_42, &pMat->_43);
			index = 0;
			break;
		}
		buffer[index++] = *lpszOther++;
	}

	pMat->_14 = pMat->_24 = pMat->_34 = 0.0f;
	pMat->_44 = 1.0f;
}

void CBspManager::SetVertices(FILE* fp)
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	int index = 0, count = 0;
	CBrush* curr = NULL;
	float x, y, z;
	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		if(!strcmp(lpszOther, "EOF"))
			break;
		
		else if(!strcmp(lpszFormer, "NAME"))
		{
			strcpy(m_pBrushs[count].m_szName, lpszOther);
			curr = &m_pBrushs[count];
			index = 0;
			count++;
		}
		
		else if(!strcmp(lpszFormer, "COUNT"))
		{
			curr->m_nVertexCount = atoi(lpszOther);
			curr->m_pVertex = new BSPVERTEX[curr->m_nVertexCount];
		}
		else if( curr )
		{
			if(curr->m_nVertexCount > 0)
			{
				//GetVertex改变 yz坐标
				GetVertex(lpszOther, &x, &y, &z);
				curr->m_pVertex[index].pos.x = x;
				curr->m_pVertex[index].pos.y = y;
				curr->m_pVertex[index].pos.z = z;
				index++;
			}
		}
	}
}

void CBspManager::SetLightInfo( FILE* fp )
{
	char lpszFormer[STR_MAX], lpszOther[STR_MAX];
	int num = 0; 
	WORD first=0, second=0, third=0;
	char ch[6];

	GetToken( fp, lpszFormer );
	while(1)
	{
		GetFormerNOther(fp, lpszFormer, lpszOther);
		for( int i = 0 ; i < 5 ; i++ )
		{
			ch[i] = lpszFormer[i];
		}
		ch[5] = '\0';
		if(!strcmp(lpszOther, "EOF"))
			break;
		else if(!strcmp(ch, "Fspot"))
		{
			num++;
		}
	}

	m_pLight = new CLight[num];
	m_nStaticLight = num;
	num = 0;

	fseek( fp, 0, SEEK_SET );
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -