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

📄 pvsengine.cpp

📁 是3D游戏一书中所讲的游戏引擎fly3D 包括fly3D引擎的源码及应用此引擎开发出来的游戏实例 有fly3D引擎的教程,易于step by step跟学
💻 CPP
字号:
#include "../../lib/Fly3D.h"
#include "pvsengine.h"
#include "opengl.h"

extern int cur_side,savelog;
extern HDC hdc;
extern short **face_nodes;
extern char file[256];
extern float VOLUME_FACTOR;
char flypathname[256];

void pvsEngine::set_pvs_bit(int node1,int node2)
{
	*(pvs + node1*pvsrowsize + (node2>>3)) |= (1<<(node2&7));
}

int pvsEngine::get_pvs_bit(int node1,int node2)
{
	return PVS_TEST(node1,node2);
}

static_mesh *pvsEngine::get_object(bsp_node *n)
{
	bsp_object *e=n->elem;
	while(e)
		{
		if (e->type==TYPE_STATIC_MESH)
			break;
		e=e->next_elem;
		}
	return (static_mesh *)e;
}

void pvsEngine::draw_bsp(bsp_node *n,vector& p,vector& z)
{
	if (n->leaf!=-1)
		{
		static_mesh *o=get_object(n);
		if (o==0)
			return;
		int i,j;
		for( i=0;i<o->objmesh->nf;i++)
			{
			if (o->objmesh->faces[i]->color.w<1.0f)
				{
				glEnd();
				glEnable(GL_POLYGON_STIPPLE);
				glBegin(GL_TRIANGLES);
				}

			j=o->objmesh->faces[i]->indx;
	
			//glColor3ub(j&255,(j>>8)&255,(j>>16)&255);
			glColor3ub( ((j&31)<<3)+7, (((j>>5)&31)<<3)+7, (((j>>10)&31)<<3)+7);

			glVertex3fv((float *)o->objmesh->faces[i]->vert[0]);
			glVertex3fv((float *)o->objmesh->faces[i]->vert[1]);
			glVertex3fv((float *)o->objmesh->faces[i]->vert[2]);

			if (o->objmesh->faces[i]->color.w<1.0f)
				{
				glEnd();
				glDisable(GL_POLYGON_STIPPLE);
				glBegin(GL_TRIANGLES);
				}
			}
		return;
		}

	float x,y;
	x=vec_dot(n->normal,z);
	y=(vec_dot(n->normal,p)+n->d0)/x;

	if (y>0)
		if(fabs(x)>0.7071)
		{
		if (x>0)
			if (n->child[0]) draw_bsp(n->child[0],p,z); else ;
		else 
			if (n->child[1]) draw_bsp(n->child[1],p,z); else ;
		return;
		}

	if (n->child[0]) draw_bsp(n->child[0],p,z);
	if (n->child[1]) draw_bsp(n->child[1],p,z);
}

void pvsEngine::render_hc_face(vector& p,vector& z,vector& u,char *buf)
{
    glLoadIdentity();
	gluLookAt( 
			p.x,p.y,p.z, 
			p.x+z.x, p.y+z.y, p.z+z.z, 
			u.x,u.y,u.z);

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	glPolygonMode(GL_FRONT,GL_FILL);
	glBegin(GL_TRIANGLES);
	draw_bsp(bsp,p,z);
	glEnd();

	glReadPixels(0,0,screen_sx,screen_sy,GL_RGB,GL_UNSIGNED_BYTE,buf);
}

void pvsEngine::update_pvs(int node,char *buf)
{
	int i,j,indx1,indx2,indx3,t=screen_sx*(screen_sy-1)-1;
	unsigned char *b=(unsigned char *)buf;

	for( i=0;i<t;i++,b+=3 )
	{
//	indx=((unsigned)*b)+((unsigned)*(b+1)<<8)+((unsigned)*(b+2)<<16);

	indx1=((unsigned)*b>>3)+((unsigned)*(b+1)>>3<<5)+((unsigned)*(b+2)>>3<<10);
	indx2=((unsigned)*(b+3)>>3)+((unsigned)*(b+4)>>3<<5)+((unsigned)*(b+5)>>3<<10);
	indx3=((unsigned)*(b+screen_sx*3)>>3)+((unsigned)*(b+screen_sx*3+1)>>3<<5)+((unsigned)*(b+screen_sx*3+2)>>3<<10);

	if (indx1>=nfaces || indx1!=indx2 || indx1!=indx3)
		continue;

	for(j=0;j<face_nodes[indx1][0];j++)
		set_pvs_bit(node, face_nodes[indx1][j+1]);
	}
}

void pvsEngine::sample_node(bsp_node *n,vector& v)
{
	vector z,u;
	
	char *buf=new char[3*screen_sx*screen_sy];

	z.vec(0,0,1);
	u.vec(1,0,0);
	render_hc_face(v,z,u,buf);
	if (cur_side==0)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);

	z.vec(0,0,-1);
	u.vec(1,0,0);
	render_hc_face(v,z,u,buf);
	if (cur_side==1)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);

	z.vec(0,1,0);
	u.vec(1,0,0);
	render_hc_face(v,z,u,buf);
	if (cur_side==2)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);

	z.vec(0,-1,0);
	u.vec(1,0,0);
	render_hc_face(v,z,u,buf);
	if (cur_side==3)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);

	z.vec(1,0,0);
	u.vec(0,0,1);
	render_hc_face(v,z,u,buf);
	if (cur_side==4)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);

	z.vec(-1,0,0);
	u.vec(0,0,1);
	render_hc_face(v,z,u,buf);
	if (cur_side==5)	SwapBuffers(hdc);
	update_pvs(n->leaf,buf);
	
	delete buf;
}

int pvsEngine::get_node_random_point(int leafnum,vector& point)
{
	static_mesh *so=(static_mesh *)leaf[leafnum]->elem;
	boundbox bb=so->objmesh->bbox;
	int i,j=10000;
	for( i=0;i<j;i++ )
	{
		point.x =
			bb.min.x+
			FABSRAND*(bb.max.x-bb.min.x);
		point.y =
			bb.min.y+
			FABSRAND*(bb.max.y-bb.min.y);
		point.z =
			bb.min.z+
			FABSRAND*(bb.max.z-bb.min.z);
		bsp_node *n=find_node(bsp,point,NEAR_PLANE_THRESHOLD);
		if (n==leaf[leafnum])
			break;
	}
	if (i==j)
		return 0;
	return 1;
}

void pvsEngine::save_pvslog(char *f)
{
	FILE *fp=fopen(f,"wt");
	if (fp)
	{
		int i,j,k,t=0;

		fprintf(fp,"nodenum\tnfaces\tnsamp\tnvis\tbboxx\tbboxy\tbboxz\n");

		for( i=0;i<nleaf;i++ )
		{
			k=0;
			for( j=0;j<nleaf;j++ )
				if (PVS_TEST(i,j))
					k++;
			t+=k;

			static_mesh *so=(static_mesh *)leaf[i]->elem;
			if(so==0)
				fprintf(fp,"%i\n",i);
			else 
			{
				vector v=so->objmesh->bbox.max-so->objmesh->bbox.min;
				float vol=v.x*v.y*v.z;
				j=(int)(vol/VOLUME_FACTOR)+1;
				fprintf(fp,"%i\t%i\t%i\t%i\t%.1f\t%.1f\t%.1f\n",
					i,so->objmesh->nf,j,k,
				so->objmesh->bbox.max.x-so->objmesh->bbox.min.x,
				so->objmesh->bbox.max.y-so->objmesh->bbox.min.y,
				so->objmesh->bbox.max.z-so->objmesh->bbox.min.z);
			}
		}

		fprintf(fp,"\nTotal: %i nodes (%i%%)\n",nleaf,t*100/(nleaf*nleaf));

		fclose(fp);
	}
}

int pvsEngine::opendata(char *f) 
{
	char str[256];
	strcpy(flypathname,f);
	*(strrchr(flypathname,'\\')+1)=0;
	strcpy(file,strrchr(f,'\\')+1);
	*strchr(file,'.')=0;

	strcpy(str,flypathname);
	strcat(str,file);
	strcat(str,".bsp");
	if (load_bsp(str)==0)
		return 0;

	alloc_pvs(0);

	face_nodes=new short *[nfaces];

	int i, j, k;
	for( i=0;i<nfaces;i++ )
	{
		face_nodes[i]=new short;
		face_nodes[i][0]=0;
	}

	for( i=0;i<nleaf;i++ )
	{
		static_mesh *o=get_object(flyengine->leaf[i]);
		if(o)
			for(j=0;j<o->objmesh->nf;j++)
			{
				k=o->objmesh->faces[j]->indx;
				short *temp=new short[face_nodes[k][0]+2];
				memcpy(temp, face_nodes[k], sizeof(short)*(face_nodes[k][0]+1));
				delete face_nodes[k];
				face_nodes[k]=temp;
				face_nodes[k][face_nodes[k][0]+1]=i;
				face_nodes[k][0]++;
			}
	}

	return 1;
}

void pvsEngine::save()
{
	char str[256];

	strcpy(str,flypathname);
	strcat(str,file);
	strcat(str,".pvs");
	save_pvs(str);

	if (savelog)
	{
	strcpy(str,flypathname);
	strcat(str,file);
	strcat(str,".pvslog.txt");
	save_pvslog(str);
	}
}

⌨️ 快捷键说明

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