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

📄 3dsimport.cpp

📁 <B>《Realtime Rendering》的随书源代码
💻 CPP
字号:
#include "../Fly3D.h"

int import3ds::read_chunk()
{
	int i=0;

	i+=fp.read(&chunkid, 2);//fread(&chunkid,1,2,fp);
	i+=fp.read(&chunklen, 4);//fread(&chunklen,1,4,fp);
	if (i!=6)
		return 0;
	if (chunklen>6)
		chunklen-=6;
	filepos+=6;
	
	return 1;
}

void import3ds::jump_chunk()
{
	fp.seek(chunklen);//fseek(fp,chunklen,SEEK_CUR);
	filepos+=chunklen;
}

void import3ds::load_chunk()
{
	if (chunk)
		delete chunk;
	chunk=new char[chunklen];
	filepos+=chunklen;
	fp.read(chunk, chunklen);//fread(chunk,chunklen,1,fp);
}

void import3ds::load_string(char *str)
{
	int a=0;

	while( (fp.read(&str[a],1)==1) && str[a++] );

	chunklen-=a;
	filepos+=a;
}

void import3ds::load_object()
{
	char objname[256];

	load_string(objname);
	read_chunk();
	switch(chunkid)
	{
		case 0x4600:
		{
			load_light(objname);
			break;
		}
		case 0x4700:
		{
			load_chunk();
			camera(objname, (float *)chunk,(float *)&chunk[12], *((float *)&chunk[24]), *((float *)&chunk[28]));
			break;
		}
		case 0x4100:
		{
			if (object_name(objname))
				load_mesh(objname);
			else jump_chunk();
			break;
		}
		default:
			jump_chunk();
	}
}

void import3ds::load_mesh(char *objname)
{
	int nvert=0,nfaces=0,ntextcoord=0,nfacematerial=0;
	char *vert=0,*faces=0,*textcoord=0,*facematerial=0;
	float local_axis[12]={ 1,0,0, 0,1,0, 0,0,1, 0,0,0 };
	int a,fpos=filepos+chunklen;
	while( filepos<fpos)
	{
		read_chunk();
		switch(chunkid)
		{
		case 0x4110:
			{
			load_chunk();
			nvert=*((unsigned short *)chunk);
			vert=chunk;
			chunk=0;
			break;
			}
		case 0x4120:
			{
			int fpos2=filepos+chunklen;
			fp.read(&nfaces, 2);//fread(&nfaces,2,1,fp);
			faces=new char[nfaces*2*4+2];
			fp.read(&faces[2], nfaces*2*4);//fread(&faces[2],nfaces*2,4,fp);
			filepos+=nfaces*2*4+2;
			*((unsigned short *)faces)=nfaces;
			while( filepos<fpos2)
				{
				read_chunk();
				switch(chunkid)
					{
					case 0x4130:
						{
						load_chunk();
						if (nfacematerial==0)
							{
							facematerial=chunk;
							chunk=0;
							nfacematerial=chunklen;
							}
						else 
							{
							char *temp=new char[nfacematerial+chunklen];
							memcpy(temp,facematerial,nfacematerial);
							memcpy(&temp[nfacematerial],chunk,chunklen);
							delete facematerial;
							facematerial=temp;
							nfacematerial+=chunklen;
							}
						break;
						}
					default: jump_chunk();
					}
				}
			break;
			}
		case 0x4140:
			{
			load_chunk();
			ntextcoord=*((unsigned short *)chunk);
			textcoord=chunk;
			chunk=0;
			}
			break;
		case 0x4160:
			{
			load_chunk();
			memcpy(local_axis,chunk,sizeof(float)*12);
			}
			break;
		default:
			jump_chunk();
		}
	}
	if (nvert!=0 && nfaces!=0)
	{
	local_axis[9]*=masterscale*scale;
	local_axis[10]*=masterscale*scale;
	local_axis[11]*=masterscale*scale;

	object3d(objname,nvert,nfaces,ntextcoord,local_axis);
	
	for( a=0;a<nvert;a++ )
	{
		float *f=(float *)(2+vert+a*12);
		f[0]*=masterscale*scale;
		f[1]*=masterscale*scale;
		f[2]*=masterscale*scale;
		vertex3(f);
	}
	
	for( a=0;a<ntextcoord;a++ )
	{
		*((float *)(6+textcoord+a*8))*=-1;
		text_coord((float *)(2+textcoord+a*8));
	}

	for( a=0;a<nfaces;a++ )
		face3((unsigned short *)(2+faces+a*8));

	a=0;
	int b,c,len;
	while( a<nfacematerial )
		{
		for( b=0;b<nmat;b++ )
			if (!stricmp(matlib[b].name,&facematerial[a]))
				break;
		c=strlen(&facematerial[a]);
		len=*((unsigned short *)&facematerial[a+c+1]);
		if (b<nmat)
			face_material(&matlib[b],len,(unsigned short *)&facematerial[a+c+3]);
		a+=len*2+c+3;
		}
	}
	if (vert)
		delete vert;
	if (faces)
		delete faces;
	if (facematerial)
		delete facematerial;
	if (textcoord)
		delete textcoord;
}

void import3ds::load_light(char *objname)
{
	float pos[3],target[3],color[3],hotspot,falloff;
	int type=0;
	int fpos=filepos+chunklen;
	fp.read(pos,12);//fread(pos,12,1,fp);
	filepos+=12;
	while( filepos<fpos )
	{
		read_chunk();
		switch(chunkid)
		{
			case 0x0010:
				load_chunk();
				color[0]=*((float *)&chunk[0]);
				color[1]=*((float *)&chunk[4]);
				color[2]=*((float *)&chunk[8]);
				break;
			case 0x0011:
				load_chunk();
				color[0]=(float)(((unsigned char)chunk[0])/255.0);
				color[1]=(float)(((unsigned char)chunk[1])/255.0);
				color[2]=(float)(((unsigned char)chunk[2])/255.0);
				break;
			case 0x4610:
				load_chunk();
				target[0]=*((float *)&chunk[0]);
				target[1]=*((float *)&chunk[4]);
				target[2]=*((float *)&chunk[8]);
				hotspot=*((float *)&chunk[12]);
				falloff=*((float *)&chunk[16]);
				type=1;
				break;

			default:
				jump_chunk();
		}
	}
	if (type)
		spotlight(objname, pos, target, color, hotspot, falloff);
	else pointlight(objname, pos, color);
}

int import3ds::import(char *name,float scalefactor)
{
	scale=scalefactor;
	//fp=fopen(name,"rb");
	if (!fp.open(name))
		return 0;

	while(read_chunk())
		switch(chunkid)
		{
		case M3DMAGIC:
		case MDATA:
			break;
		case MASTER_SCALE:
			{
			load_chunk();
			masterscale=*((float *)chunk);
			}
			break;
		case NAMED_OBJECT:
			load_object();
			break;
		case MAT_ENTRY:
			load_material();
			matlib[nmat-1].ambient[3]=matlib[nmat-1].transparency;
			matlib[nmat-1].diffuse[3]=matlib[nmat-1].transparency;
			matlib[nmat-1].specular[3]=matlib[nmat-1].transparency;
			break;
		default:
			jump_chunk();
		}

	fp.close();//fclose(fp);
	return 1;
}

void import3ds::load_mapping(struct mapping *m)
{
	int fpos=filepos+chunklen;

	m->u_scale=1.0;
	m->v_scale=1.0;
	m->u_offset=0.0;
	m->v_offset=0.0;
	m->rotation=0.0;

	while( filepos<fpos )
	{
		read_chunk();
		switch(chunkid)
		{
		case 0x0030:
			load_chunk();
			m->amount=*((short int *)chunk);
			break;
		case 0xA300:
			load_string(m->filename);
			break;
		case 0xA351:
			load_chunk();
			m->options=*((short int *)chunk);
			break;
		case 0xA353:
			load_chunk();
			m->filtering=*((float *)chunk);
			break;
		case 0xA354:
			load_chunk();
			m->u_scale=*((float *)chunk);
			break;
		case 0xA356:
			load_chunk();
			m->v_scale=*((float *)chunk);
			break;
		case 0xA358:
			load_chunk();
			m->u_offset=*((float *)chunk);
			break;
		case 0xA35A:
			load_chunk();
			m->v_offset=*((float *)chunk);
			break;
		case 0xA35C:
			load_chunk();
			m->rotation=*((float *)chunk);
			break;
		default:
			jump_chunk();
		}
	}
}

void import3ds::load_material()
{
	int fpos=filepos+chunklen;
	while( filepos<fpos )
	{
		read_chunk();
		switch(chunkid)
		{
			case 0xA000:
				if (matlib)
					{
					material *temp=new material[nmat+1];
					memcpy(temp,matlib,sizeof(material)*nmat);
					delete matlib;
					matlib=temp;
					} else matlib=new material;
				load_string(matlib[nmat].name);
				nmat++;
				break;
			case 0xA010:
				load_chunk();
				matlib[nmat-1].ambient[0]=(float)(((unsigned char)chunk[6])/255.0);
				matlib[nmat-1].ambient[1]=(float)(((unsigned char)chunk[7])/255.0);
				matlib[nmat-1].ambient[2]=(float)(((unsigned char)chunk[8])/255.0);
				break;
			case 0xA020:
				load_chunk();
				matlib[nmat-1].diffuse[0]=(float)(((unsigned char)chunk[6])/255.0);
				matlib[nmat-1].diffuse[1]=(float)(((unsigned char)chunk[7])/255.0);
				matlib[nmat-1].diffuse[2]=(float)(((unsigned char)chunk[8])/255.0);
				break;
			case 0xA030:
				load_chunk();
				matlib[nmat-1].specular[0]=(float)(((unsigned char)chunk[6])/255.0);
				matlib[nmat-1].specular[1]=(float)(((unsigned char)chunk[7])/255.0);
				matlib[nmat-1].specular[2]=(float)(((unsigned char)chunk[8])/255.0);
				break;
			case 0xA040:
				load_chunk();
				matlib[nmat-1].shininess=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA041:
				load_chunk();
				matlib[nmat-1].shininess_strength=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA050:
				load_chunk();
				matlib[nmat-1].transparency=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA052:
				load_chunk();
				matlib[nmat-1].transparency_falloff=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA053:
				load_chunk();
				matlib[nmat-1].reflect_blur=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA100:
				load_chunk();
				matlib[nmat-1].material_type=*((short *)chunk);
				break;
			case 0xA084:
				load_chunk();
				matlib[nmat-1].self_illum=(float)(((unsigned char)chunk[6])/100.0);
				break;
			case 0xA200:
				load_mapping(&matlib[nmat-1].map_texture1);
				break;
			case 0xA33A:
				load_mapping(&matlib[nmat-1].map_texture2);
				break;
			case 0xA210:
				load_mapping(&matlib[nmat-1].map_opacity);
				break;
			case 0xA230:
				load_mapping(&matlib[nmat-1].map_bump);
				break;
			case 0xA204:
				load_mapping(&matlib[nmat-1].map_specular);
				break;
			case 0xA33C:
				load_mapping(&matlib[nmat-1].map_shininess);
				break;
			case 0xA33D:
				load_mapping(&matlib[nmat-1].map_selfillum);
				break;
			case 0xA220:
				load_mapping(&matlib[nmat-1].map_reflection);
				break;
			default:
				jump_chunk();
		}
	}
}

⌨️ 快捷键说明

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