📄 3dsload.cpp
字号:
/* WG function*/void ReadDefaultMaterial(H3dsMeshObj *meshobj, word nf){ word face=0; char name[50]; H3dsMatList *binding; int n; binding = EnlargeBindingsArray(meshobj); meshobj->NumBindings = 1; //首先是材质的名称 /* The material name is first */ strcpy(binding->name, "WG_DEFAULT");
strcpy(name, "WG_DEFAULT");//add by JiangZibin
//然后是多边形的个数 /* Then the number of faces */ binding->NumFaces = (int)nf; binding->faces = (word *)(malloc(sizeof(face)*nf)); //将多边形与材质捆绑到一起 /* Bind the faces to the material */ for (n=0; n<nf; n++) { binding->faces[n] = n; }} /* End WG Function */ /********************************************************************************************* Eats a triangle mesh, which is a combination of XYZ vertices, faces, and bindings of material to faces. *******************************************************************************************/
//读入形体的数据结构
//对形体的描述包括:用三维坐标定义的顶点列表、三角形列表以及为每个面指定的材质等。void ReadTriMeshBlocks(dword p, char *name){ word id; word fl; /* WG */ dword len, pc; H3dsMeshObj *meshobj; int found_facemat; meshobj = EnlargeMeshArray(); found_facemat = 0; strcpy(meshobj->name, name); while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((int)id) {
//若是顶点列表块 case CHUNK_VERTLIST:
//读入顶点列表信息
ReadVertList (meshobj);
break;
//若是三角形列表块 case CHUNK_FACELIST:
//读入三角形列信息
fl = ReadFaceList(meshobj);
break; /* WG */
//若是纹理映射列表块 case CHUNK_MAPLIST:
//读入纹理映射列表
ReadMapList(meshobj);
break;
//若是平移矩阵 case CHUNK_TRMATRIX:
//读入平移矩阵
ReadTraMatrix(meshobj);
break;
//若是材质对应的面列表块 case CHUNK_FACEMAT:
//读入材质对应的面列表
ReadFaceMaterial(meshobj);
found_facemat = 1;
break; /* case CHUNK_SMOOLIST: */
//其他块简单地跳过这个块 default:
dsetpos(pc+len); } } //若没有指定面所对应的材质 if (!found_facemat) {
//则使用默认材质 defaultmaterialwarning = 1; ReadDefaultMaterial(meshobj, fl); /*W.G.*/ }}/********************************************************************************************** Reads in object blocks, which are cameras, meshes, or lights; this code only supports meshes and ignores the rest ********************************************************************************************/
//读入物体块(4000)
//物体块中包括相机、形体或光照等信息,这里只处理形体信息,而简单地跳过其他类型的信息。void ReadObjBlocks(dword p){ word id; dword len, pc; char name[16]; //第一项总是物体的名称 /* The object name is always the first item */ int n=0; do { dread(&name[n++], 1); } while(name[n-1]!='\0' && n<sizeof(name)); name[n-1]='\0'; while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((int)id) { case CHUNK_TRIMESH:
ReadTriMeshBlocks(pc+len, name);
break; /* case CHUNK_LIGHT: case CHUNK_CAMERA: */ default:
dsetpos(pc+len); } }
dsetpos(p);//是否要}//读入材质的名称/* Reads in the name of the material */void ReadMatChunk(dword p, H3dsMat *mat) { int n; char name[MAXNAMESIZE]; n = 0;
//材质的名称是一个0结尾串 do { dread(&name[n++], 1); } while(name[n-1]!='\0' && n<sizeof(name)); name[n-1]='\0'; strcpy(mat->name, name);}//读入浮点型的颜色三元组
//对于颜色的存储,3DS有两种RGB方式,一种是用浮点型RGB值表示,另一种是用字节型的RGB值表示。/* Reads in an RGB FP triplet */void ReadRGBFloat(dword p, H3dsRGBColor *rgb) { dread(&rgb->red, sizeof(float32)); dread(&rgb->green, sizeof(float32)); dread(&rgb->blue, sizeof(float32));}void ReadCorrectRGBFloat(dword p, H3dsRGBColor *rgb) {
H3dsRGBColor *temprgb=NULL;
dread(&temprgb->red, sizeof(float32));
dread(&temprgb->green, sizeof(float32));
dread(&temprgb->blue, sizeof(float32));
//不懂什么叫gamma纠正
rgb->red+=temprgb->red;
rgb->green+=temprgb->green;
rgb->blue+=temprgb->blue;
}//读字节型颜色三元组的函数,将其转换成浮点存储型/* Reads in an RGB byte triplet */void ReadRGBByte(dword p, H3dsRGBColor *rgb) { unsigned char red, green, blue; dread(&red, sizeof(red)); dread(&green, sizeof(green)); dread(&blue, sizeof(blue)); rgb->red = (float32)((red)/255.0f); rgb->green = (float32)((green)/255.0f); rgb->blue = (float32)((blue)/255.0f);}void ReadCorrectRGBByte(dword p, H3dsRGBColor *rgb) {
unsigned char red, green, blue;
dread(&red, sizeof(red));
dread(&green, sizeof(green));
dread(&blue, sizeof(blue));
rgb->red+= (float32)((red)/255.0f);
rgb->green+= (float32)((green)/255.0f);
rgb->blue+= (float32)((blue)/255.0f);
}
//读入一个阴影块/* Reads in a color assignment */void ReadShadingChunk(dword p, H3dsRGBColor *rgb) { word id; dword len, pc; while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((unsigned int)id) { case CHUNK_RGB1:
ReadRGBFloat(pc+len, rgb);
break; case CHUNK_RGB2:
ReadRGBByte(pc+len, rgb);
break;
case CHUNK_RGB3:
ReadCorrectRGBByte(pc+len, rgb);
break;
case CHUNK_RGB4:
ReadCorrectRGBFloat(pc+len, rgb);
break; default:
dsetpos(pc+len); } }}//读入纹理的名称,纹理的名称也是一个0结尾串void ReadTextureNameChunk(dword p, H3dsTexture *texture) { int n; char name[MAXNAMESIZE];// word id;// dword len, pc; n = 0; do { dread(&name[n++], 1); } while(name[n-1]!='\0' && n<sizeof(name)); name[n-1]='\0'; strcpy(texture->texturename, name);}//读入纹理,只读纹理的名称,其他信息全部忽略。void ReadTextureChunk(dword p, H3dsTexture *texture) { unsigned short id; dword len, pc; while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((unsigned int)id) { case CHUNK_MAPFILENAME: ReadTextureNameChunk(pc+len, texture); break; default: dsetpos(pc+len); } }} //置材质为双面材质/********************************************************************************************** * I assume that if one material is doublesided, they all are, * so turn on a global doublesided flag *********************************************************************************************/
//假定若一个材质为双面的,则所有材质都是双面的,因此可以用一个全局变量来标识材质为双面的。void ReadDoublesidedChunk(int *material_doublesided) { *material_doublesided = 1; doublesided = 1;} //void ReadAmountChunk(word *amount) {
word temp;
dread(&temp, sizeof(temp));
*amount = temp;
}
//I interpret the transparency information as the alpha
// value for the entire material
void ReadAlphaChunk(dword p, float32 *alpha) {
word id;
dword len, pc;
word amount;
while((pc=dgetpos()) < p) {
dread(&id, sizeof(id));
dread(&len, sizeof(len));
switch((unsigned int)id) {
case CHUNK_AMOUNT:
ReadAmountChunk(&amount);
break;
default:
dsetpos(pc+len);
}
}
*alpha = (float32)(amount / 100.0);
if (*alpha < .01)
*alpha = 1.0;
else
alphablending = 1;
}
// Fills out the current material with the information contained // in these chunks//读入当前材质块的信息
//材质块中的信息包含几种类型,它可以是其名称或其环境光成分、漫反射
//光成分、镜面反射光成分或者是纹理或双面光属性等。各种子类型信息都
//以子块的形式加以定义。void ReadMaterialBlocks(dword p){ unsigned short id; dword len, pc; H3dsMat *materialobj = EnlargeMatObjArray(); while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((unsigned int)id) {
//材质名称块 case CHUNK_MATNAME: /*0xA000*/ ReadMatChunk(pc+len, materialobj); break;
//材质环境光成分 case CHUNK_AMBIENT: /*0xA010*/ ReadShadingChunk(pc+len, &materialobj->ambient); break;
//材质漫反射光成分 case CHUNK_DIFFUSE: /*0xA020*/ ReadShadingChunk(pc+len, &materialobj->diffuse); break;
//材质的镜面反射光成分 case CHUNK_SPECULAR:/*0xA030*/ ReadShadingChunk(pc+len, &materialobj->specular); break;
//纹理子块 case CHUNK_TEXTURE: /*0xA200*/ ReadTextureChunk(pc+len, &materialobj->texture); break;
//是否使用双面材质 case CHUNK_DOUBLESIDED:/*0xA081*/ ReadDoublesidedChunk(&materialobj->doublesided); break;
case CHUNK_TRANSPARENCY:/*0xA050*/
ReadAlphaChunk(pc+len, &materialobj->alpha);
break;
//其他类型的子块,跳过去 default: dsetpos(pc+len); break; } }}//读入形体对象块及材质/* Reads in mesh objects and materials */void ReadObjMeshBlocks(dword p){ unsigned short id; dword len, pc; while((pc=dgetpos()) < p) { dread(&id, sizeof(id)); dread(&len, sizeof(len)); switch((unsigned int)id) { case CHUNK_MATERIAL: /*0xAFFF*/ ReadMaterialBlocks(pc+len); break; case CHUNK_OBJBLOCK: /*0x4000*/ ReadObjBlocks(pc+len); break; default:
dsetpos(pc+len); } }}// Reads in objects; this would be the start of where keyframer support would// be added//读入物体主块
//3DS中共定义了2种主块,一种是编辑器主块,另一种是关键帧主块,由于这里只是
//要将物体的形体读入并显示,而不涉及任何动画信息的处理,因此跳过关键帧信息
//块。若要在程序中加入对关键帧的支持,也可以从这里开始。void ReadMainBlocks(dword p){ word id; dword len, pc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -