3DS文件结构

 

文档版本:0.93   –   1997.1
作者:Martin   van   Velsen(重写)
            Robin   Fercoq(重写)
            Jim   Pitts(原版)
            Albert   Szilvasy(原代码)
翻译:樱
From:GameRes   http://www.gameres.com

还有许多“块”我并没有写入本文档中,这是因为我并不知道他们有什么用,如果你知道的话请来信告诉我。当我获得更多关于3ds文件结构的信息的时候,我将重写这篇文档。
这篇文档描述了由AutoDesk公司的3ds   max产生的3ds文件的结构,因此你将无法从AutoDesk公司以及其他任何与AutoDesk公司有关系的公司获得有关二进制的.3ds和.mli文件的性质和内容的任何支持。
警告:本文档描述了版本号为3.0或更高版本的.3ds文件,你可以获得.3ds的版本信息,这些信息在二进制的.3ds文件中第29字节处(译者:似乎不在,版本号在块ID为:0x0002的块里)。

现在就要开始我们的内容了,我将按照如下的方式组织内容:
1.介绍。
2.所有的“块”
3.3D编辑块
4.关键帧块
5.代码 

1.介绍
3ds文件结构是由“块”组成的。它们描述了接在它们后面的数据的信息,即这些数据是如何组成的。“块”是由两部分组成的:1.ID;2.下一个数据块的位置。也就是说,如果你不明白这个块的用处,你可以迅速地跳过它。因为下一个数据区的相对位置(字节数)已经得到了。二进制的3ds文件是用一种特殊的方法写成的:也就是低字节在前,高字节在后(译者:二进制文件都是这样的)。举例来说,4A   5C(十六进制,2个字节)实际上是数字:5C   4A,4A   是低字节,5C是高字节。对于4字节整数:4A   5C   3B   8F实际上是8F   3B   5C   4A,3B   8F是高字节,4A   5C是低字节。那么现在解释一下“块”,“块”被定义成如下的样子:

unsigned   short   ID;//2个字节,无符号的,块的ID
unsigned   long   Length;//4个字节,无符号的,描述了下一个数据区对于当前数据区的位置,实际上就是本数据区的大小。

每个块是一个层次结构,由ID表示。3ds文件有一个主块,ID是0x4D4D。这个块永远是3ds文件的开始(译者:可以用它来鉴定本文件是否为一个3ds文件)。在开始块里面就是主要块了。为了使大家清晰地查看,研究这个层次结构,下面给出一个图表,用来显示他们的不同ID以及他们在文件中的位置。这些ID都被命名,这是因为在图表后面以这些名字对应着他们的ID定义了一个列表。将他们写入原代码会变的更简单(本文档包含着这些便利的样例代码)。

MAIN3DS     (0x4D4D)
                                    |
                                    +--EDIT3DS     (0x3D3D)
                                    |     |
                                    |     +--EDIT_MATERIAL   (0xAFFF)
                                    |     |     |
                                    |     |     +--MAT_NAME01   (0xA000)   (See   mli   Doc)  
                                    |     |
                                    |     +--EDIT_CONFIG1     (0x0100)
                                    |     +--EDIT_CONFIG2     (0x3E3D)  
                                    |     +--EDIT_VIEW_P1     (0x7012)
                                    |     |     |
                                    |     |     +--TOP                         (0x0001)
                                    |     |     +--BOTTOM                   (0x0002)
                                    |     |     +--LEFT                       (0x0003)
                                    |     |     +--RIGHT                     (0x0004)
                                    |     |     +--FRONT                     (0x0005)  
                                    |     |     +--BACK                       (0x0006)
                                    |     |     +--USER                       (0x0007)
                                    |     |     +--CAMERA                   (0xFFFF)
                                    |     |     +--LIGHT                     (0x0009)
                                    |     |     +--DISABLED               (0x0010)    
                                    |     |     +--BOGUS                     (0x0011)
                                    |     |
                                    |     +--EDIT_VIEW_P2     (0x7011)
                                    |     |     |
                                    |     |     +--TOP                         (0x0001)
                                    |     |     +--BOTTOM                   (0x0002)
                                    |     |     +--LEFT                       (0x0003)
                                    |     |     +--RIGHT                     (0x0004)
                                    |     |     +--FRONT                     (0x0005)  
                                    |     |     +--BACK                       (0x0006)
                                    |     |     +--USER                       (0x0007)
                                    |     |     +--CAMERA                   (0xFFFF)
                                    |     |     +--LIGHT                     (0x0009)
                                    |     |     +--DISABLED               (0x0010)    
                                    |     |     +--BOGUS                     (0x0011)
                                    |     |
                                    |     +--EDIT_VIEW_P3     (0x7020)
                                    |     +--EDIT_VIEW1         (0x7001)  
                                    |     +--EDIT_BACKGR       (0x1200)  
                                    |     +--EDIT_AMBIENT     (0x2100)
                                    |     +--EDIT_OBJECT       (0x4000)
                                    |     |     |
                                    |     |     +--OBJ_TRIMESH       (0x4100)            
                                    |     |     |     |
                                    |     |     |     +--TRI_VERTEXL                     (0x4110)  
                                    |     |     |     +--TRI_VERTEXOPTIONS         (0x4111)
                                    |     |     |     +--TRI_MAPPINGCOORS           (0x4140)  
                                    |     |     |     +--TRI_MAPPINGSTANDARD     (0x4170)
                                    |     |     |     +--TRI_FACEL1                       (0x4120)
                                    |     |     |     |     |
                                    |     |     |     |     +--TRI_SMOOTH                         (0x4150)      
                                    |     |     |     |     +--TRI_MATERIAL                     (0x4130)
                                    |     |     |     |
                                    |     |     |     +--TRI_LOCAL                         (0x4160)
                                    |     |     |     +--TRI_VISIBLE                     (0x4165)
                                    |     |     |
                                    |     |     +--OBJ_LIGHT         (0x4600)
                                    |     |     |     |
                                    |     |     |     +--LIT_OFF                             (0x4620)
                                    |     |     |     +--LIT_SPOT                           (0x4610)  
                                    |     |     |     +--LIT_UNKNWN01                   (0x465A)  
                                    |     |     |  
                                    |     |     +--OBJ_CAMERA       (0x4700)
                                    |     |     |     |
                                    |     |     |     +--CAM_UNKNWN01                   (0x4710)
                                    |     |     |     +--CAM_UNKNWN02                   (0x4720)    
                                    |     |     |
                                    |     |     +--OBJ_UNKNWN01   (0x4710)
                                    |     |     +--OBJ_UNKNWN02   (0x4720)
                                    |     |
                                    |     +--EDIT_UNKNW01     (0x1100)
                                    |     +--EDIT_UNKNW02     (0x1201)  
                                    |     +--EDIT_UNKNW03     (0x1300)
                                    |     +--EDIT_UNKNW04     (0x1400)
                                    |     +--EDIT_UNKNW05     (0x1420)
                                    |     +--EDIT_UNKNW06     (0x1450)
                                    |     +--EDIT_UNKNW07     (0x1500)
                                    |     +--EDIT_UNKNW08     (0x2200)
                                    |     +--EDIT_UNKNW09     (0x2201)
                                    |     +--EDIT_UNKNW10     (0x2210)
                                    |     +--EDIT_UNKNW11     (0x2300)
                                    |     +--EDIT_UNKNW12     (0x2302)
                                    |     +--EDIT_UNKNW13     (0x2000)
                                    |     +--EDIT_UNKNW14     (0xAFFF)
                                    |
                                    +--KEYF3DS   (0xB000)
                                          |
                                          +--KEYF_UNKNWN01   (0xB00A)
                                          +--.............   (0x7001)   (   viewport,   same   as   editor   )
                                          +--KEYF_FRAMES       (0xB008)
                                          +--KEYF_UNKNWN02   (0xB009)
                                          +--KEYF_OBJDES       (0xB002)
                                                |
                                                +--KEYF_OBJHIERARCH     (0xB010)
                                                +--KEYF_OBJDUMMYNAME   (0xB011)
                                                +--KEYF_OBJUNKNWN01     (0xB013)
                                                +--KEYF_OBJUNKNWN02     (0xB014)
                                                +--KEYF_OBJUNKNWN03     (0xB015)    
                                                +--KEYF_OBJPIVOT           (0xB020)    
                                                +--KEYF_OBJUNKNWN04     (0xB021)    
                                                +--KEYF_OBJUNKNWN05     (0xB022)    

颜色块是一种在整个文件中都能找到的块。其名字为:
1.   COL_RGB
2.   COL_TRU
3.   COL_UNK

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

3.3D编辑块

到现在为止已经大概都介绍完了,现在开始研究细节信息。
0x4D4D是文件头,他的大小就是整个文件的大小。

另外还有两个主要块,他们是3D编辑块和关键帧块:
0x3D3D:3D编辑块,描述了3D对象的数据。3D对象就在这个地方。
0xB000:关键帧块,描述了关键帧数据。

在某个主要块之后有一些数据块。这些应该是其他一些允许在主要块之内的数据(请参见图表)。
0x3D3D的子块:
ID         描述
            0100     配置部分
            1100     unknown
            1200     背景色
  1201     unknown
  1300     unknown
  1400     unknown
  1420     unknown
  1450     unknown
  1500     unknown
  2100     环境色
  2200     雾?
  2201     雾   ?
  2210     雾   ?
  2300     unknown
  3000     unknown
  3D3E     配置编辑块
  4000     对象数据块
  AFFF     材质列表

子块AFFF,定义了材质。其子块A000定义了材质名称。材质名称是ASCLL字符,以0x00为结束符。

子块3D3E,配置编辑块:
                  ID           描述
                7001     视口指示器
                7011     视口定义   (   类型   2   )
                7012     视口定义(     类型   1   )
7020     视口定义(     类型   3   )

3D3E块中有很多变态的数据,其中只有7020块比较重要,这个块定义了4个活动的视口。假设在编辑程序中使用了4个视口,编辑程序配置中包含5个7020块和5个7011块。但是事实上只有开始的4个7020块对用户的视口外观有影响,其他的里面只包含一些附加信息。该块的第6,7字节表明了视图的类型,合法的ID以及其对应的视图如下所示:
ID         描述
  0001       顶
  0002       底
  0003       左
  0004       右
  0005       前
  0006       后
      0007       用户
  FFFF       摄象机
  0009       光源
  0010       无效

子块4000是一个对象描述块。该块的开始是一个由0结尾的字符串,描述了该对象的名称。要记住,对象不仅仅是一个物体,也可能是一个光源或者是一个摄象机:
ID                 描述
      4010           unknown
      4012           阴影?
      4100           三角形列表
      4600           光源
      4700           摄象机

子块4100三角形列表的子块:
          ID                 描述
        4110           顶点列表
    4111           顶点选项
        4120           面列表
  4130           面材质
  4140           纹理映射
        4150           面平滑组
        4160           平移矩阵
        4165           物体可见性
        4170           标准映射

其中4110顶点列表块的数据:
数据类型 大小 名称
Unsigned   short 2字节 顶点数目
Float 4字节 X坐标
Float 4字节 Y坐标
float 4字节 Z坐标
其中X,Y,Z一直重复顶点数目次,这样就得到了所有的顶点。

4111顶点选项块:
该块由一些整数组成,第一个整数表明了顶点的个数,然后对每个顶点用一个整数表示一些位信息。其中0~7,11~12位影响物体的可见性,8~10位是随机信息,13~15位表明该顶点是否在某个选择集中被选中。该块不很重要。即使丢失此块,3DS仍旧能够将文件正确的载入。

4120面列表块:
数据类型 大小 名称
Unsigned   short 2字节 面数量
Unsigned   short 2字节 顶点A的索引
Unsigned   short 2字节 顶点B的索引
Unsigned   short 2字节 顶点C的索引
Unsigned   short 2字节 面信息
其中顶点A,B,C和面信息重复面数量次就得到了所有的面。面信息的各位意义如下:
位数 意义
1 AC边的顺序。若是A-> C的话为1。
2 BC边的顺序。若是B-> C的话为1。
3 AB边的顺序。若是A-> B的话为1。
4 映射
5 未使用
6 同上
7 同上
8 同上
9 同上
10 混乱
11 混乱
12 0
13 0
14 是否在选择集3被选中
15 是否在选择集2被选中
16 是否在选择集1被选中
4130面材质块:
如果一个对象只使用默认材质的话便没有面材质块。事实上,每一个对象使用的材质都有一个面材质块。每一个面材质块都以一个以0结尾的字符串开始,接着由一个数字表示使用该材质的面的数量(2个字节),接着就是面描述。0000表示面列表中的第一个面。

4140纹理映射块:
开始的两个字节表示了顶点的数量,然后为每个顶点定义2个浮点数的纹理坐标。也就是说,如果一个顶点的纹理映射在纹理的中心,那么其坐标就是(0.5,0.5)。

4150面平滑组块(译者:至今本人不知道这个块的用处……):
面的数量乘上4个字节,即每个数据是一个4字节的整数,第N个数字表示该面是否属于第N个平滑组。

4160平移矩阵块:
开始的3个浮点数定义了物体局部坐标在绝对坐标中的位置,最后3个浮点数定义了物体的局部中心。

4170标准映射块(译者:至今本人不知道这个块的用处……):
开始的2个字节表示了映射类型:0表示平面映射或者是指定映射;1:圆柱映射;2:球映射。接着用21个浮点数描述该映射。

4600光源块:
开始用3个浮点数(共12字节)描述了该光源的X,Y,Z坐标位置,接下来是如下数据块:
ID                     描述
              0010               RGB色
              0011           24位色块
              4610           该光源是个聚光灯
              4620           布尔值,表示该光源的有效性

其中,4610块的数据:
开始的3个浮点数表示了聚光灯指向的方向(X,Y,Z)。接下来的一个浮点数表示了热点。最后一个浮点数表示了发散(译者:好像就是聚光的角度)。

0010   RGB色块:
用3个浮点数表示了物体的R,G,B色。

0011   24位色块:
用3个字节描述了物体的R,G,B色(译者:即每分色一字节)。

4700摄像机块:
开始的3个浮点数表示了摄像机的位置(X,Y,Z),中间的3个浮点数表示了摄像机指向的位置(X,Y,Z),接下来的一个浮点数表示了摄像机的旋转角(译者:不知道什么用……),最后一个浮点数表示了摄像机的镜头角度(译者:就是视角)。

4.关键帧块
关键帧块:
ID                       描述
  B00A                 unknown
                7001                 看该块的第一个描述而定(译者:完全不知道什么用,从来没在.3ds文件中见过这个块)
  B008                 帧数量
  B009                 unknown
                B002                 开始对象描述

其中,B008帧数量块:由8字节组成(unsigned   long   X   2),开始4个字节描述了开始帧,最后4个字节描述了结束帧。

B002物体信息块:
            ID                   描述
  B010           名称与层次结构
        B011*         哑元物体命名(译者:也就是不在场景中显示的对象,一般用来对对象分组)
        B013             unknown
        B014*           unknown
  B015             unknown
        B020             物体转轴(中心点)
B021             unknown
        B022             unknown

B010名称与层次结构块:
该块由一个以0结尾的字符串开始,中间4个字节(unsigned   short   X   2)未知,最后2个字节(unsigned   short)表示了物体层次结构。物体的层次结构并不复杂,场景中的没一个物体被给予一个数字以表示其在场景树中的顺序。3ds文件中也使用了这种方法来表示在场景中出现的对象在场景树中的位置。作为根的物体被给予数字-1(FFFF)作为其数字标识。当读取文件的时候,就会得到一系列的物体数字标识。如果当前数字标识比前一个大,那么当前物体是前一个物体的子物体;如果当前数字标识比前一个小,那么又回到了上层结构。例如:
        物体名称     层次结构
                A             -1
                B               0                                     这个例子来自
                C               1                                     50pman.3ds
                D               2
                E               1  
                F               4  
                G               5  
                H               1
                I               7
                J               8
                K               0
                L             10
                M             11
                N               0
                O             13
                P             14
             
即:
                                                                  A
                  +-----------------+----------------+
                  B                                   K                                 N
        +----+----+                         |                                 |
        C         E         H                         L                                 O
        |         |         |                         |                                 |
        D         F         I                         M                                 P
                  |         |
                  G         J

然而该块并没有结束!
如果一个物体被叫做:$$$DUMMY的话,他就是一个哑元物体!因此你就需要一些额外的数据块了。
B011:哑元物体名称,一个以0结尾的字符串。
B020:物体转轴,仍然不知道前5个浮点数是做什么用的。
开始     结束   大小   类型           描述
              0         3         4     float     unknown
              4         7         4     float     unknown
              8       11         4     float     unknown
            12       16         4     float     unknown
            16       19         4     float     unknown
            20       23         4     float     unknown
            24       27         4     float     转轴Y
            28       32         4     float     转轴X

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值