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

📄 bspmanager.cpp

📁 BSP地形系统和光照贴图的技术详解
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -