📄 bspmanager.cpp
字号:
// 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 + -