3DS格式文件按块解析(Java版)

3DS文件格式

在3ds文件中,所有数据都是以块的形式进行存储的,下面是块中的文件格式。理解了块,那我们就能够对3ds文件进行解析了。
Alt

3DS块

chunk是3ds文件的基本构成单位。每一个chunk包括一个头和一个主体。chunk是相互嵌套的,这就决定了你必须以递归的方式读取它们。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:无

长度:头长度+内容长度

内容:名称(以空字节结尾的字符串)

0xa200:纹理帖图。

父chunk:0xafff

子chunk:0xa300

长度:头长度+子chunk长度

内容:无

0xa300:帖图名称。

父chunk:0xa200

子chunk:无

长度:头长度+内容长度

内容:名称(以空字节结尾的字符串)

0xB000:关键帧主chunk,包含所有的关键帧信息。

父chunk:0x4D4D

子chunk:0xB008、0xB002

长度:头长度+子chunk长度

内容:无

0xB008:关键帧的起点和终点。

父chunk:0xB000

子chunk:无

长度:头长度+内容长度

内容:起始帧(一个双字)结尾帧(一个双字)

块解析代码

先将整个3ds文件以10进制数组读入,然后将整个数组分块读取。

// 读取对应块信息
		String[] res = new String[6];
        TChunk tChunk = new TChunk();
        for(int i = 0; i < 6; i++){
            res[i] = intToString(results[(int) (index+i)]);
        }
        String name = res[1]+res[0];
        String length = res[5]+res[4]+res[3]+res[2];

        tChunk.setChunkId(name);
        tChunk.setChunkIndex(index);
        tChunk.setChunkLength(Long.parseLong(length, 16));
        return tChunk;

通过读取出来的对应块ID进行分别处理

// 读取对应块信息
		switch (tChunk.getChunkId()){
                case "4D4D":
                    x = 1;
                    index += 6;
                    tChunk.setChunkDescription("文件标志头块");
                    break;
                case "3D3D":
                    x = 1;
                    index += 6;
                    tChunk.setChunkDescription("网格对象的版本号");
                    break;
                case "4000":
                    if(index+tChunk.getChunkLength()==results.length){
                        x = 2;
                    }
                    else {
                        x = 1;
                    }
                    index += tChunk.getChunkLength();
                    tChunk.setChunkDescription("对象块");
                    t3DObject = ReadBinary.readT3DObject(results,tChunk);
                    t3DObjects.add(t3DObject);
                    break;
                case "0002":
                    x = 1;
                    index += tChunk.getChunkLength();
                    tChunk.setChunkDescription(".3ds文件的版本块");
                    break;
                default:
                    if(index+tChunk.getChunkLength()==results.length){
                        x = 2;
                    }
                    else {
                        x = 1;
                    }
                    index += tChunk.getChunkLength();
            }
            tChunks.add(tChunk);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值