现在是时候向我们就亲爱的立方体说再见的时候了!在本篇教程中,我们将创建一个程序来加载3ds物体,一个在Internet上非常流行的文件格式,并被许多不同的3d建模器所支持。一个3D建模器允许你以一种更加直观和人性化的方式创建任何类型的物体,而不是手工定义顶点的坐标,即使对于比一个立方体稍微复杂一点的简单物体,这将是一个不可能完成的任务。实际上,我不情愿放弃立方体,这样一个简单而又完美的形状。无论如何,除非是被证明不是,宇宙飞船,行星,导弹和任何与空间模拟器有关的东西看起来和立方体完全不同。
在写代码之前,有必要分析一下3ds文件的结构。
好的,放上你写程序时最喜欢喝的饮料并准备开始吧... 
3DS文件结构
一个3ds文件包含一系列的信息用于描述由一个或多个物体组成的3D场景的所有细节。一个3ds文件包含了一系列的块,称之为chunks。那么在这些块中又包含了什么了?是需要描述场景的所有信息:每个物体的名称,顶点坐标,映射坐标,多边形列表,表面的颜,动画关键帧等等...
这些chunks没有一个线性的结构。这意味着一些chunks依赖于其他的chunks,并只有在它们的父chunks被读入后才能读入。没有必要读入所有的chunks,我们在此只考虑最为重要的。我对3ds文件格式的描述基于包含在中的信息,此由Jochen Wjlhelmy所写,详细地解释了所有chunks的结构。
一个Chunk包含4个字段:
Identifier:一个两个字节长的16进制的数字以标识chunk。这个信息立即地告诉我们对于我们的意图此chunk是否有用。如果我们需要这个chunk,我们可以提取(extrapolate)包含在这个chunk和可能的子chunk中的信息。如果我们不需要这个chunk,我们使用一下信息来跳过它...
Length of the chunk:一个4字节数字,表示chunk长度和其所有子chunk长度的总和。
Chunk data:这个字段有一个变量长度并包含场景的所有数据。
下表显示了在一个典型的chunk中各字段的偏移和长度(以字节为单位)。
Offset
Length
 
0
2
Chunk identifier
2
4
Chunk length: chunk data + sub-chunks(6+n+m)
6
n
Data
6+n
m
Sub-chunks
我们可以从表的最后一行清楚地看到一些chunks是如何依赖于其他chunks的:每个子chunk实际上是包含在父chunkSub-chunks”字段。
以下是在一个3ds文件中最为重要的chunks。请注意不同元素间的层次关系:
MAIN CHUNK 0x4D4D
  3D EDITOR CHUNK 0x3D3D
      OBJECT BLOCK 0x4000
        TRIANGULAR MESH 0x4100
            VERTICES LIST 0x4110
            FACES DESCRIPTION 0x4120
              FACES MATERIAL 0x4130
            MAPPING COORDINATES LIST 0x4140
              SMOOTHING GROUP LIST 0x4150
            LOCAL COORDINATES SYSTEM 0x4160
        LIGHT 0x4600
            SPOTLIGHT 0x4610
        CAMERA 0x4700
      MATERIAL BLOCK 0xAFFF
        MATERIAL NAME 0xA000
        AMBIENT COLOR 0xA010
        DIFFUSE COLOR 0xA020
        SPECULAR COLOR 0xA030
        TEXTURE MAP 1 0xA200
        BUMP MAP 0xA230
        REFLECTION MAP 0xA220
        [SUB CHUNKS FOR EACH MAP]
            MAPPING FILENAME 0xA300
            MAPPING PARAMETERS 0xA351
      KEYFRAMER CHUNK 0xB000
        MESH INFORMATION BLOCK 0xB002
        SPOT LIGHT INFORMATION BLOCK 0xB007
        FRAMES (START AND END) 0xB008
            OBJECT NAME 0xB010
            OBJECT PIVOT POINT 0xB013
            POSITION TRACK 0xB020
            ROTATION TRACK 0xB021
            SCALE TRACK 0xB022
            HIERARCHY POSITION 0xB030
如前所述,如果我们想读取一个特殊的chunk,我们必须要先读取它的父chunk。想象一下3ds文件是一棵树,我们要读取的chunk是一片叶子(并且我们是地面上的一个小蚂蚁)。为了达到叶子,我们需要从树干开始,并穿过通向叶子的所有树枝。例如,如果我们想到达chunk VERTICES LIST,我们必须先读取MAIN CHUNK,然后是3D EDITOR CHUNKOBJECT BLOCK,最后是chunk TRIANGULAR MESH。其他的chunks可以安全地跳过。
现在让我们剪除树,只剩下将在本教程中使用的树枝:vertices, faces, mapping coordinates 和它们的父chunks
MAIN CHUNK 0x4D4D
  3D EDITOR CHUNK 0x3D3D
      OBJECT BLOCK 0x4000
        TRIANGULAR MESH 0x4100
            VERTICES LIST 0x4110
            FACES DESCRIPTION 0x4120
            MAPPING COORDINATES LIST 0x4140
下面是chunks的详细描述:
MAIN CHUNK
Identifier
0x4d4d 
Length
0 + sub-chunks length
Chunk father
None
Sub chunks
3D EDITOR CHUNK
Data
None
3D EDITOR CHUNK
Identifier
0x3D3D 
Length
0 + sub-chunks length
Chunk father
MAIN CHUNK
Sub chunks
OBJECT BLOCK, MATERIAL BLOCK, KEYFRAMER CHUNK
Data
None
OBJECT BLOCK
Identifier
0x4000
Length
Object name length + sub-chunks length
Chunk father
3D EDITOR CHUNK
Sub chunks
TRIANGULAR MESH, LIGHT, CAMERA
Data
Object name
TRIANGULAR MESH
Identifier
0x4100
电脑软件editor
Length
0 + sub-chunks length
Chunk father
OBJECT BLOCK
Sub chunks
VERTICES LIST, FACES DESCRIPTION, MAPPING COORDINATES LIST
Data
None
VERTICES LIST
Identifier
0x4110
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
None
Data
Vertices number (unsigned short)
Vertices list: x1,y1,z1,x2,y2,z2 etc. (for each vertex: 3*float)
FACES DESCRIPTION
Identifier
0x4120
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
FACES MATERIAL
Data
Polygons number (unsigned short)
Polygons list: a1,b1,c1,a2,b2,c2 etc. (for each point: 3*unsigned short)
Face flag: face options, sides visibility etc. (unsigned short)
MAPPING COORDINATES LIST
Identifier
0x4140
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
SMOOTHING GROUP LIST
Data
Vertices number (unsigned short)
Mapping coordinates list: u1,v1,u2,v2 etc. (for each vertex: 2*float)
现在3ds文件格式相当清楚了,我们现在看看本篇教程的代码。什么?你已经完全迷惑了?让我们继续吧,随着本篇教程的讲述,对你来说,chunk”的结构将会变得越来越清晰。毕竟,我们是程序员,我们能更好地理解C,而不是喋喋不休的讲述。
简短的摘要
我们加载3ds物体并保存到我们的引擎所定义的格式需要的步骤是:
-实现一个while”循环(正如我们为纹理加载器所做的),不断地执行直到到达文件的结束。
-每个循环的反复读入chunk idchunk length
-使用一个switch分析chunk id的内容。
-如果chunk是我们不需要读入的树的一部分,我们移动文件指针到一个新的位置来跳过那个chunk长度,即通过将当前位置加上当前chunk的长度。这使得我们可以跳过任何我们不需要读入的chunk和子chunk。换句话说:让我们跳到另外一个树枝!你是否有自己是猴子的感觉?:)
-如果chunk允许到达我们需要的其他chunk,或是包含了我们需要的数据,那么我们就根据需要来读取数据,然后我们移动到下一个chunk

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。