📄 bspmanager.cpp
字号:
if (split->a == 1)
mid.x = -split->d;
else if (split->a == -1)
mid.x = split->d;
else
mid.x = p1.x + dot*( p2.x - p1.x );
if (split->b == 1)
mid.y = -split->d;
else if (split->b == -1)
mid.y = split->d;
else
mid.y = p1.y + dot*( p2.y - p1.y );
if (split->c == 1)
mid.z = -split->d;
else if (split->c == -1)
mid.z = split->d;
else
mid.z = p1.z + dot*( p2.z - p1.z ) ;
VectorCopy (mid, neww->vPoint[neww->n]);
neww->n++;
}
if (neww->n > maxpts)
; //error
// free the original winding
delete in;
return neww;
}
void CBspManager::DivideWinding (CWinding *in, D3DXPLANE *split, CWinding **front, CWinding **back)
{
float dists[MAX_POINTS_ON_WINDING];
int sides[MAX_POINTS_ON_WINDING];
int counts[3];
float dot;
int i, j;
D3DXVECTOR3 p1, p2;
D3DXVECTOR3 mid;
CWinding *f, *b;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point
for (i=0 ; i<in->n ; i++)
{
D3DXVECTOR3 normal = D3DXVECTOR3( split->a, split->b, split->c );
dot = D3DXVec3Dot( &in->vPoint[i], &normal );
dot = dot + split->d;
dists[i] = dot;
if (dot > EPSILON)
sides[i] = SIDE_FRONT;
else if (dot < -EPSILON)
sides[i] = SIDE_BACK;
else
{
sides[i] = SIDE_ON;
}
counts[sides[i]]++;
}
sides[i] = sides[0];
dists[i] = dists[0];
*front = *back = NULL;
if (!counts[0])
{
*back = in;
return;
}
if (!counts[1])
{
*front = in;
return;
}
maxpts = in->n+4; // can't use counts[0]+2 because
// of fp grouping errors
*front = f = new CWinding();
*back = b = new CWinding();
for (i=0 ; i<in->n ; i++)
{
p1 = in->vPoint[i];
if (sides[i] == SIDE_ON)
{
VectorCopy (p1, f->vPoint[f->n]);
f->n++;
VectorCopy (p1, b->vPoint[b->n]);
b->n++;
continue;
}
if (sides[i] == SIDE_FRONT)
{
VectorCopy (p1, f->vPoint[f->n]);
f->n++;
}
if (sides[i] == SIDE_BACK)
{
VectorCopy (p1, b->vPoint[b->n]);
b->n++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
// generate a split point
p2 = in->vPoint[(i+1)%in->n];
dot = dists[i] / (dists[i]-dists[i+1]);
// avoid round off error when possible
if (split->a == 1)
mid.x = -split->d;
else if (split->a == -1)
mid.x = split->d;
else
mid.x = p1.x + dot*(p2.x - p1.x);
if (split->b == 1)
mid.y = -split->d;
else if (split->b == -1)
mid.y = split->d;
else
mid.y = p1.y + dot*(p2.y - p1.y);
if (split->c == 1)
mid.z = -split->d;
else if (split->c == -1)
mid.z = split->d;
else
mid.z = p1.z + dot*(p2.z - p1.z);
VectorCopy (mid, f->vPoint[f->n]);
f->n++;
VectorCopy (mid, b->vPoint[b->n]);
b->n++;
}
if (f->n > maxpts || b->n > maxpts)
; //error
}
void CBspManager::ClearOutsideFace( )
{
CheckInside( m_pBspRoot );
}
void CBspManager::CheckInside( CBspNode * node )
{
CBspNode::CPortal *p, *nextp, *prev = NULL;
if ( !node->m_bIsLeaf )
{
CheckInside ( node->m_pFront );
CheckInside ( node->m_pBack );
}
for (p=node->m_pPortals ; p ; p=nextp)
{
if (p->m_pNode[0] == node)
nextp = p->m_pNext[0];
else
nextp = p->m_pNext[1];
if( p->m_bRender )
{
CFace * curr = NULL, * next = NULL, * copy = NULL;
for( curr = p->m_pNode[0]->m_pFaceList ; curr ; curr = next )
{
next = curr->m_pNext;
if( !curr->m_bInside )
{
curr->m_bInside = TRUE;
copy = CFace::CreateFace();
CBrush::FaceCopy( curr, copy );
copy->m_nPlane = curr->m_nPlane;
copy->m_pNext = m_pNewFaceRoot;
m_pNewFaceRoot = copy;
}
}
for( curr = p->m_pNode[1]->m_pFaceList ; curr ; curr = next )
{
next = curr->m_pNext;
if( !curr->m_bInside )
{
curr->m_bInside = TRUE;
copy = CFace::CreateFace();
CBrush::FaceCopy( curr, copy );
copy->m_nPlane = curr->m_nPlane;
copy->m_pNext = m_pNewFaceRoot;
m_pNewFaceRoot = copy;
}
}
}
}
}
void CBspManager::SetThingInfo( FILE* fp, CThing* &pThing )
{
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"))
{
pThing = new CThing();
break;
}
}
}
void CBspManager::SetThingVertices( FILE* fp, CThing* &pThing )
{
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
int index = 0, count = 0;
float x, y, z;
GetToken( fp, lpszFormer );
while(1)
{
GetFormerNOther(fp, lpszFormer, lpszOther);
if(!strcmp(lpszOther, "EOF"))
break;
else if(!strcmp(lpszFormer, "NAME"))
{
}
else if(!strcmp(lpszFormer, "COUNT"))
{
pThing->m_nVertexCount = atoi(lpszOther);
pThing->m_pVertex = new BSPVERTEX[pThing->m_nVertexCount];
}
else if( pThing->m_nVertexCount > 0 )
{
//GetVertex改变 yz坐标
GetVertex(lpszOther, &x, &y, &z);
pThing->m_pVertex[index].pos.x = x;
pThing->m_pVertex[index].pos.y = y;
pThing->m_pVertex[index].pos.z = z;
index++;
}
}
}
void CBspManager::SetThingFaceIndex( FILE* fp, CThing* &pThing )
{
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
int num = 0;
WORD first=0, second=0, third=0;
GetToken( fp, lpszFormer );
while(1)
{
GetFormerNOther(fp, lpszFormer, lpszOther);
if(!strcmp(lpszOther, "EOF"))
break;
else if(!strcmp(lpszFormer, "NAME"))
{
num = 0;
}
else if(!strcmp(lpszFormer, "COUNT"))
{
pThing->m_nFaceCount = atoi(lpszOther);
pThing->m_pTriangleIndex = new TRIANGLEINDEX[pThing->m_nFaceCount];
}
else if(pThing->m_nFaceCount > 0)
{
//GetIndex中,相互改变 first和 third.
GetIndex(lpszOther, &first, &second, &third);
pThing->m_pTriangleIndex[num]._0 = first;
pThing->m_pTriangleIndex[num]._1 = second;
pThing->m_pTriangleIndex[num]._2 = third;
num++;
}
}
}
void CBspManager::SetThingMaterial( FILE* fp, CThing* &pThing )
{
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
int num = 0;
GetToken( fp, lpszFormer );
if( strcmp( lpszFormer, "MATERIAL") )
return;
while(1)
{
GetFormerNOther(fp, lpszFormer, lpszOther);
if(!strcmp(lpszOther, "EOF"))
break;
else if(!strcmp(lpszFormer, "TEXTURE"))
{
num++;
}
}
if( num <= 0 )
return;
pThing->m_nTexCnt = num;
pThing->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( pThing->m_pTXData[num++].name, lpszOther );
}
}
}
void CBspManager::SetThingTXVertices( FILE* fp, CThing* &pThing )
{
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
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"))
;
else if(!strcmp(lpszFormer, "COUNT"))
{
pThing->m_nTCount = atoi(lpszOther);
pThing->m_pTVtx = new D3DXVECTOR3[pThing->m_nTCount];
num = 0;
}
else if(pThing->m_nTCount > 0)
{
GetVertex(lpszOther, &x, &y, &z);
pThing->m_pTVtx[num].x = x;
pThing->m_pTVtx[num].y = y;
//max中,由于 v上升增加为1
//D3D中, v下降增加至1
pThing->m_pTVtx[num].z = 1.f - z;
num++;
}
}
}
void CBspManager::SetThingTXIndex( FILE* fp, CThing* &pThing )
{
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
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"))
;
else if(!strcmp(lpszFormer, "COUNT"))
{
pThing->m_nTFCount = atoi(lpszOther);
pThing->m_pTIndex = new TRIANGLEINDEX[pThing->m_nTFCount];
num = 0;
}
else if(pThing->m_nTFCount > 0)
{
GetIndex(lpszOther, &first, &second, &third);
pThing->m_pTIndex[num]._0 = first;
pThing->m_pTIndex[num]._1 = second;
pThing->m_pTIndex[num++]._2 = third;
}
}
}
void CBspManager::SetThingTXName( FILE* fp, CThing* &pThing )
{
/*
char lpszFormer[STR_MAX], lpszOther[STR_MAX];
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"))
;
else if(!strcmp(lpszFormer, "TEXTURE"))
{
if( m_pStaticThing )
{
m_pStaticThing->m_nTexture = m_pStaticThing->GetTextureIndex( lpszOther );
}
}
}
*/
}
void CBspManager::LoadThings( LPDIRECT3DDEVICE8 pd3dDevice )
{
char tmpFileName[STR_MAX];
char* szFileName = "things\\thing_light";
FILE* fp;
//Thing 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".nfo");
fp = fopen(tmpFileName, "r");
SetThingInfo( fp, m_pStaticThing );
fclose( fp );
//VERTEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".vtx");
fp = fopen(tmpFileName, "r");
SetThingVertices( fp, m_pStaticThing );
fclose( fp );
//FACE INDEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".idx");
fp = fopen(tmpFileName, "r");
SetThingFaceIndex( fp, m_pStaticThing );
fclose( fp );
//MATERIAL 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".mat");
fp = fopen(tmpFileName, "r");
SetThingMaterial( fp, m_pStaticThing );
fclose( fp );
//TEXTURE VERTEX信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".vtt");
fp = fopen(tmpFileName, "r");
SetThingTXVertices( fp, m_pStaticThing );
fclose( fp );
//TVERTEX INDEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".idt");
fp = fopen(tmpFileName, "r");
SetThingTXIndex( fp, m_pStaticThing );
fclose( fp );
/*
//TEXTURE NAME 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".txn");
fp = fopen(tmpFileName, "r");
SetThingTXName( fp, m_pStaticThing );
fclose( fp );
*/
m_pStaticThing->InitThing();
D3DXCreateTextureFromFile( pd3dDevice, m_pStaticThing->m_pTXData->name, &m_pStaticThing->m_pTXData->texture );
szFileName = "things\\dynamicthing";
//Thing 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".nfo");
fp = fopen(tmpFileName, "r");
SetThingInfo( fp, m_pDynamicThing );
fclose( fp );
//VERTEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".vtx");
fp = fopen(tmpFileName, "r");
SetThingVertices( fp, m_pDynamicThing );
fclose( fp );
//FACE INDEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".idx");
fp = fopen(tmpFileName, "r");
SetThingFaceIndex( fp, m_pDynamicThing );
fclose( fp );
//MATERIAL 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".mat");
fp = fopen(tmpFileName, "r");
SetThingMaterial( fp, m_pDynamicThing );
fclose( fp );
//TEXTURE VERTEX信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".vtt");
fp = fopen(tmpFileName, "r");
SetThingTXVertices( fp, m_pDynamicThing );
fclose( fp );
//TVERTEX INDEX 信息
strcpy(tmpFileName, szFileName);
strcat(tmpFileName, ".idt");
fp = fopen(tmpFileName, "r");
SetThingTXIndex( fp, m_pDynamicThing );
fclose( fp );
m_pDynamicThing->InitThing();
D3DXCreateTextureFromFile( pd3dDevice, m_pDynamicThing->m_pTXData->name, &m_pDynamicThing->m_pTXData->texture );
}
CBspNode* CBspManager::Build(LPSTR szFileName, LPDIRECT3DDEVICE8 pd3dDevice)
{
m_billboard.v[0].pos = D3DXVECTOR3( -2, 2, 0 );
m_billboard.v[0].u = 0.f;
m_billboard.v[0].v = 0.f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -