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

📄 flymesh.cpp

📁 <B>《Realtime Rendering》的随书源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (faces[i]->ray_intersect(ro,rd,tmp_ip,tmp_dist,rad))
			if (tmp_dist<dist)
			{
			dist=tmp_dist;
			ip=tmp_ip;
			f=i;
			}

	return f;
}

int mesh::ray_intersect_test(vector& ro,vector& rd,float rad)
{
	static vector tmp_ip;
	static float tmp_dist;
	int i;

	for( i=0;i<nf;i++ )
		if (faces[i]->ray_intersect(ro,rd,tmp_ip,tmp_dist,rad))
			if (tmp_dist<0.99f)
				return 1;
	return 0;
}

void face::inverse_map(vector& p, float& u, float& v)
{
	vector v1=*vert[1]-*vert[0],
		v2=*vert[2]-*vert[0],
		ip=p-*vert[0];

	float det;

	det=v1.x*v2.y-v1.y*v2.x;
	if(det!=0.0f)
	{
		u=(ip.x*v2.y-ip.y*v2.x)/det;
		v=(v1.x*ip.y-v1.y*ip.x)/det;
		return;
	}

	det=v1.x*v2.z-v1.z*v2.x;
	if(det!=0.0f)
	{
		u=(ip.x*v2.z-ip.z*v2.x)/det;
		v=(v1.x*ip.z-v1.z*ip.x)/det;
		return;
	}

	det=v1.y*v2.z-v1.z*v2.y;
	u=(ip.y*v2.z-ip.z*v2.y)/det;
	v=(v1.y*ip.z-v1.z*ip.y)/det;
}

void face::forward_map(float& u,float& v,vector& p)
{
	p.x=vert[0]->x+
		(vert[1]->x-vert[0]->x)*u+
		(vert[2]->x-vert[0]->x)*v;
	p.y=vert[0]->y+
		(vert[1]->y-vert[0]->y)*u+
		(vert[2]->y-vert[0]->y)*v;
	p.z=vert[0]->z+
		(vert[1]->z-vert[0]->z)*u+
		(vert[2]->z-vert[0]->z)*v;
}

void mesh::illum_faces(vector& ip,float d_max,vector& c,int shadows)
{
	if (lastdraw<flyengine->cur_frame_base || (flyengine->mapmode&MAPPING_LIGHTMAP)==0)
		return;

	light_map *lm;
	int i;

	for( i=0;i<nf;i++ )
		if(faces[i]->lm!=-1)
			{
			lm=flyengine->lm[faces[i]->lm];
			if (lm->lastupdate!=flyengine->cur_step)
				if (fabs(faces[i]->distance(ip))<d_max)
					{
					lm->illum(ip,c,d_max,shadows);
					lm->lastupdate=flyengine->cur_step;
					}
			}
}

mesh *static_mesh::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,int &facenum,float rad)
{
	if (objmesh)
	{
		facenum=objmesh->ray_intersect(ro,rd,ip,dist,rad);
		if (facenum!=-1)
			return objmesh;
	}
	return 0;
}

int static_mesh::ray_intersect_test(vector& ro,vector& rd,float rad)
{
	if (objmesh)
		if (objmesh->ray_intersect_test(ro,rd,rad))
			return 1;
	return 0;
}

int static_mesh::message(vector& p,float rad,int msg,int param,void *data)
{
	if (msg==FLYOBJM_ILLUM)
		if (objmesh)
			objmesh->illum_faces(p,rad,*((vector *)data),param);
	return 0;
}

void anim_mesh::reset()
{
	if (ao_vert) delete ao_vert;
	if (ao_bbox) delete ao_bbox;
	if (stripfancount) delete stripfancount;
	if (stripfanvert) delete stripfanvert;
	if (vertdata) delete vertdata;
	nframes=0;
	ao_vert=0;
	ao_bbox=0;
	nstripfan=0;
	nstripfanvert=0;
	stripfancount=0;
	stripfanvert=0;
	vertdata=0;
}

void anim_mesh::compute_bbox()
{
	int i,j,k=nv;
	vector *v=ao_bbox;
	for( i=0;i<nframes;i++ )
	{
		v[0].vec(BIG,BIG,BIG);
		v[1].vec(-BIG,-BIG,-BIG);
		for( j=k-nv;j<k;j++ )
		{
			if (ao_vert[j].x<v[0].x)
				v[0].x=ao_vert[j].x;
			if (ao_vert[j].y<v[0].y)
				v[0].y=ao_vert[j].y;
			if (ao_vert[j].z<v[0].z)
				v[0].z=ao_vert[j].z;

			if (ao_vert[j].x>v[1].x)
				v[1].x=ao_vert[j].x;
			if (ao_vert[j].y>v[1].y)
				v[1].y=ao_vert[j].y;
			if (ao_vert[j].z>v[1].z)
				v[1].z=ao_vert[j].z;
		}
		v+=2;
		k+=nv;
	}
}

int anim_mesh::load_fao(char *name)
{
	reset();
	fly_pak fp;
	if (fp.open(name))
		{
		int i;
		char skin[256];
		float *ao_uv;
		short *ao_face;

		fp.read(&i,sizeof(int));
		if (i!=9171)
			{
			fp.close();
			return 0;
			}

		fp.read(&nf,sizeof(int));
		fp.read(&nv,sizeof(int));
		fp.read(&nframes,sizeof(int));
		fp.read(&pivotpos,3*sizeof(float));
		fp.read(skin,64);

		ao_vert=new vector[nv*nframes];
		ao_bbox=new vector[2*nframes];
		ao_uv=new float[6*nf];
		ao_face=new short[3*nf];

		fp.read(ao_face,nf*sizeof(short)*3);
		fp.read(ao_uv,nf*sizeof(float)*6);
		for( i=0;i<nv*nframes;i++ )
			fp.read(&ao_vert[i],sizeof(float)*3);

		fp.read(&nstripfan,sizeof(int));
		if (nstripfan)
		{
		stripfancount=new int[nstripfan];
		fp.read(stripfancount,nstripfan*sizeof(int));
		fp.read(&nstripfanvert,sizeof(int));
		stripfanvert=new int[nstripfanvert];
		vertdata=new vertex[nstripfanvert];
		for( i=0;i<nstripfanvert;i++ )
			{
			fp.read(&vertdata[i].u,sizeof(float));
			fp.read(&vertdata[i].v,sizeof(float));
			fp.read(&stripfanvert[i],sizeof(int));
			}
		}

		fp.close();

		texpic=flyengine->get_picture(skin);
		if (texpic==-1)
			{
			if (strrchr(name,'\\'))
				strcpy(skin,strrchr(name,'\\')+1);
			else if (strrchr(name,'/'))
				strcpy(skin,strrchr(name,'/')+1);
			else strcpy(skin,name);
			if (strrchr(skin,'.'))
				*strrchr(skin,'.')=0;
			strcat(skin,".tga");
			texpic=flyengine->get_picture(skin);
			if (texpic==-1)
				{
				if (strrchr(skin,'.'))
					*strrchr(skin,'.')=0;
				strcat(skin,".jpg");
				texpic=flyengine->get_picture(skin);
				}
			}

		vert=new vector[nv];
		localfaces=new face[nf];
		faces=new face *[nf];

		for( i=0;i<nf;i++ )
			{
			faces[i]=&localfaces[i];
			localfaces[i].vert[0]=&vert[ao_face[i*3]];
			localfaces[i].vert[1]=&vert[ao_face[i*3+1]];
			localfaces[i].vert[2]=&vert[ao_face[i*3+2]];
			localfaces[i].uv[0][0]=ao_uv[i*6];
			localfaces[i].uv[0][1]=ao_uv[i*6+1];
			localfaces[i].uv[1][0]=ao_uv[i*6+2];
			localfaces[i].uv[1][1]=ao_uv[i*6+3];
			localfaces[i].uv[2][0]=ao_uv[i*6+4];
			localfaces[i].uv[2][1]=ao_uv[i*6+5];
			localfaces[i].color.vec(1,1,1,1);
			localfaces[i].lastdraw=0;
			localfaces[i].normal.null();
			}
		
		delete ao_face;
		delete ao_uv;
		ao_face=0;
		ao_uv=0;

		set_key(0);
		compute_normals(MESH_FACENORM|MESH_VERTNORM|MESH_BBOX|MESH_EDGES);
		compute_bbox();

		return 1;
		}
	return 0;
}

void anim_mesh::set_key(float key)
{
	if (key>=0.0f && key<=1.0f)
	{
	int i,j,k;
	float s;
	vector *v,*v0,*v1;
	j=(int)(key*nframes);
	if (j==nframes)
		{ j=0; key=0.0f; }
	s=1.0f/nframes;
	key=(key-j*s)/s;
	v0=&ao_vert[j*nv];
	if (j==nframes-1)
		k=0;
	else k=j+1;
	v1=&ao_vert[k*nv];
	v=vert;
	for( i=0;i<nv;i++,v++,v0++,v1++ )
		*v=*v0+(*v1-*v0)*key;

	bbox.min=ao_bbox[j*2]+(ao_bbox[k*2]-ao_bbox[j*2])*key;
	bbox.max=ao_bbox[j*2+1]+(ao_bbox[k*2+1]-ao_bbox[j*2+1])*key;
//	compute_normals(MESH_FACENORM|MESH_VERTNORM);
	}
}

void anim_mesh::set_key(int key)
{
	if (key>=0 && key<nframes)
	{
	memcpy(vert,&ao_vert[key*nv],sizeof(vector)*nv);

	bbox.min=ao_bbox[key*2];
	bbox.max=ao_bbox[key*2+1];
	compute_normals(MESH_FACENORM|MESH_VERTNORM);
	}
}

void mesh::implode(float mindist)
{
	if (vert==0) 
		return;

	char *f=new char[nv];
	memset(f,1,nv);

	int i,j,k,v;
	for( i=0;i<nv;i++ )
	 if (f[i])
	 for( j=i+1;j<nv;j++ )
		if (f[j])
		if ((vert[i]-vert[j]).length()<mindist)
		{
		f[j]=0;
		for( k=0;k<nf;k++ )
		 for( v=0;v<3;v++ )
			if (localfaces[k].vert[v]==&vert[j])
				localfaces[k].vert[v]=&vert[i];
		}

	for( i=0;i<nv;i++ )
		if (f[i]==0)
		{
		for( k=0;k<nf;k++ )
			for( v=0;v<3;v++ )
				if (localfaces[k].vert[v]-vert>i)
					localfaces[k].vert[v]=localfaces[k].vert[v]-1;
		memcpy(&vert[i],&vert[i+1],sizeof(vector)*(nv-i-1));
		memcpy(&f[i],&f[i+1],nv-i-1);
		nv--;
		i--;
		}

	delete f;
}


void mesh::set_numverts(int nverts,int keep)
{
	vector *tmp=new vector[nverts];
	if(keep)
		if (nverts>=nv)
			memcpy(tmp,vert,sizeof(vector)*nv);
		else 
			memcpy(tmp,vert,sizeof(vector)*nverts);
	nv=nverts;
	if (vert)
		delete vert;
	vert=tmp;
}

void mesh::set_numfaces(int nfaces,int local,int keep)
{
	face **tmp1=new face *[nfaces];
	if(keep)
		if (nfaces>=nf)
			memcpy(tmp1,faces,sizeof(face *)*nf);
		else 
			memcpy(tmp1,faces,sizeof(face *)*nfaces);
	if (faces)
		delete faces;
	faces=tmp1;
	if (local)
	{
		face *tmp2=new face[nfaces];
		if(keep)
			if (nfaces>=nf)
				memcpy(tmp2,localfaces,sizeof(face)*nf);
			else 
				memcpy(tmp2,localfaces,sizeof(face)*nfaces);
		if (localfaces)
			delete localfaces;
		localfaces=tmp2;
	}
	nf=nfaces;
}

⌨️ 快捷键说明

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