2.所有的块
现在你会看到我将使用define来定义这些数字。然而因为这里有一些新的块,这些块并没有记录到最初的文档中,因此各位要留心。
//------ 初始块
#define MAIN3DS 0x4D4D
//------ 主块
#define EDIT3DS 0x3D3D // this is the start of the editor config
#define KEYF3DS 0xB000 // this is the start of the keyframer config
//------ 3DS编辑块的子块
#define EDIT_MATERIAL 0xAFFF
#define EDIT_CONFIG1 0x0100
#define EDIT_CONFIG2 0x3E3D
#define EDIT_VIEW_P1 0x7012
#define EDIT_VIEW_P2 0x7011
#define EDIT_VIEW_P3 0x7020
#define EDIT_VIEW1 0x7001
#define EDIT_BACKGR 0x1200
#define EDIT_AMBIENT 0x2100
#define EDIT_OBJECT 0x4000
#define EDIT_UNKNW01 0x1100
#define EDIT_UNKNW02 0x1201
#define EDIT_UNKNW03 0x1300
#define EDIT_UNKNW04 0x1400
#define EDIT_UNKNW05 0x1420
#define EDIT_UNKNW06 0x1450
#define EDIT_UNKNW07 0x1500
#define EDIT_UNKNW08 0x2200
#define EDIT_UNKNW09 0x2201
#define EDIT_UNKNW10 0x2210
#define EDIT_UNKNW11 0x2300
#define EDIT_UNKNW12 0x2302
#define EDIT_UNKNW13 0x3000
#define EDIT_UNKNW14 0xAFFF
//------ 对象块的子块
#define OBJ_TRIMESH 0x4100
#define OBJ_LIGHT 0x4600
#define OBJ_CAMERA 0x4700
#define OBJ_UNKNWN01 0x4010
#define OBJ_UNKNWN02 0x4012 //---- 阴影块
//------ 摄象机块的子块
#define CAM_UNKNWN01 0x4710
#define CAM_UNKNWN02 0x4720
//------ 光源块的子块
#define LIT_OFF 0x4620
#define LIT_SPOT 0x4610
#define LIT_UNKNWN01 0x465A
//------ 三角形列表块的子块
#define TRI_VERTEXL 0x4110
#define TRI_FACEL2 0x4111
#define TRI_FACEL1 0x4120
#define TRI_SMOOTH 0x4150
#define TRI_LOCAL 0x4160
#define TRI_VISIBLE 0x4165
//------ 关键帧快的子块
#define KEYF_UNKNWN01 0xB009
#define KEYF_UNKNWN02 0xB00A
#define KEYF_FRAMES 0xB008
#define KEYF_OBJDES 0xB002
//------ 下面定义了颜色块
#define COL_RGB 0x0010
#define COL_TRU 0x0011
#define COL_UNK 0x0013
//------ 定义视口块
#define TOP 0x0001
#define BOTTOM 0x0002
#define LEFT 0x0003
#define RIGHT 0x0004
#define FRONT 0x0005
#define BACK 0x0006
#define USER 0x0007
#define CAMERA 0x0008 // 0xFFFF is the actual code read from file
#define LIGHT 0x0009
#define DISABLED 0x0010
#define BOGUS 0x0011
我自己在后面补充几个块的详细介绍吧。
首先我说一下文件的读取规则,3ds文件的读取规则如下:
字节:直接读取;
字:先读低位字节,后读高位字节,如ed 3c读出后的字为3c ed;
双字:先读低位字,后读高位字,如ed 3c 25 43读出后的双字为43 25 3c ed;
浮点数:直接读取四个字节。
3ds文件由chunk构成,每一个chunk包括一个头和一个主体。chunk是相互嵌套的,这就决定了你必须以递归的方式读取它们。chunk的头又由两部分组成:ID和chunk的长度,其中ID占一个字,chunk长度占(以字节为单位,包括头)一个双字。ID表示chunk的含义。事实上有上千个chunk,它们构成了一个复杂但灵活的文件系统,你不需要知道所有的就可以顺利的读完整个文件。
下面是其中某些主要chunk的介绍:
0x4D4D:根chunk,每一个3ds文件都起自它,它的长度也就是文件的长度。它包含了两个chunk:编辑器,和关键帧。
父chunk:无
子chunk:0x3D3D、0xB000
长度:头长度+子chunk长度
内容:无
0x3D3D:编辑器主chunk,它包含有:网格信息、灯光信息、摄象机信息和材质信息。
父chunk:0x4D4D
子chunk:0x4000、0xafff
长度:头长度+子chunk长度
内容:无
0x4000:网格主chunk,它包含了所有的网格。
父chunk:0x3D3D
子chunk:0x4100
长度:头长度+子chunk长度+内容长度
内容:
名称(以空字节结尾的字符串)
0x4100:网格信息,包含网格名称、顶点、面、纹理坐标等。
父chunk:0x4000
子chunk:0x4110、0x4120、0x4140、0x4160
长度:头长度+子chunk长度
内容:无
0x4110:顶点信息。
父chunk:0x4100
子chunk:无
长度:头长度+内容长度
内容:
顶点个数(一个字)
顶点坐标(三个浮点数一个坐标x、y、z,个数*3*浮点数)
0x4120:面信息。
父chunk:0x4100
子chunk:0x4130
长度:头长度+子chunk长度+内容长度
内容:
面个数(一个字)
顶点索引(三个字一个索引1、2、3,个数*3*字)
0x4130:与网格相关的材质信息。
父chunk:0x4120
子chunk:无
长度:头长度+内容长度
内容:
名称(以空字节结尾的字符串)
与材质相连的面的个数(一个字)
与材质相连的面的索引(个数*字)
0x4140:纹理坐标。
父chunk:0x4100
子chunk:无
长度:头长度+内容长度
内容:
坐标个数(一个字)
坐标(两个浮点数一个坐标u、v,个数*2*浮点数)
0x4160:转换矩阵。
父chunk:0x4100
子chunk:无
长度:头长度+内容长度
内容:
x轴的向量(三个浮点数u、v、n)
y轴的向量(三个浮点数u、v、n)
z轴的向量(三个浮点数u、v、n)
源点坐标(三个浮点数x、y、z)
0xafff:材质信息。
父chunk:0x4D4D
子chunk:0xa000、0xa020、0xa200
长度:头长度+子chunk长度
内容:无
0xa000:材质名称。
父chunk:0xafff
子chunk:无
长度:头长度+内容长度
内容:
名称(以空字节结尾的字符串)
0xa020:满射色。
父chunk:0xafff
子chunk:0x0011、0x0012
长度:头长度+子chunk长度
内容:无
0xa200:纹理帖图。
父chunk:0xafff
子chunk:0xa300
长度:头长度+子chunk长度
内容:无
0xa300:帖图名称。
父chunk:0xa200
子chunk:无
长度:头长度+内容长度
内容:
名称(以空字节结尾的字符串)
0xB000:关键帧主chunk,包含所有的关键帧信息。
父chunk:0x4D4D
子chunk:0xB008、0xB002
长度:头长度+子chunk长度
内容:无
0xB008:关键帧的起点和终点。
父chunk:0xB000
子chunk:无
长度:头长度+内容长度
内容:
起始帧(一个双字)
结尾帧(一个双字)
0xB002:网格的关键帧信息。
父chunk:0xB000
子chunk:0xB010、0xB011、0xB013、0xB020、0xB021、0xB022、0xB030
长度:头长度+子chunk长度
内容:无
0xB010:关键帧的层次信息,包括名称和上一级关键帧的索引,名称与它指向的网格名称一致。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
名称(以空字节结尾的字符串)
两个未知的字
上一级关键帧的索引(一个字)
0xB011:关键帧的dummy名称,我不知道dummy在这里的具体含义,但只要你在上一个chunk中读到的名称是“$$$DUMMY”那么你就要到这里来读它真正的名称。因为这说明它指向的不是网格而是虚拟的组。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
名称(以空字节结尾的字符串)
0xB013:支点坐标。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
三个浮点数x,y,z
0xB020:移动的关键帧信息。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
五个未知的字
帧个数(一个字)
一个个数那么多的循环结构{
帧索引(一个字)
一个未知的双字
移动的向量(三个浮点数x,y,z)
}
0xB021:转动的关键帧信息。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
五个未知的字
帧个数(一个字)
一个个数那么多的循环结构{
帧索引(一个字)
一个未知的双字
转动角度(一个浮点数)
绕之转动的向量(三个浮点数x,y,z)
}
0xB022:缩放的关键帧信息。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
五个未知的字
帧个数(一个字)
一个个数那么多的循环结构{
帧索引(一个字)
一个未知的双字
伸缩的向量(三个浮点数x,y,z)
}
0xB030:关键帧的索引。
父chunk:0xB002
子chunk:无
长度:头长度+内容长度
内容:
关键帧的索引(一个字)
以下的chunk可能出现在任何chunk中:
0x0010:浮点数格式的颜色。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
颜色(三个浮点数red,green,blue)
0x0011:字节格式的颜色。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
颜色(三个字节red,green,blue)
0x0012:字节格式的gamma矫正。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
颜色(三个字节red,green,blue)
0x0013:浮点数格式的gamma矫正。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
颜色(三个浮点数red,green,blue)
0x0030:字格式的百分比。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
百分比(一个字0~100)
0x0031:浮点数格式的百分比。
父chunk:任何可能的chunk
子chunk:无
长度:头长度+内容长度
内容:
百分比(一个浮点数0~100)