Now we'll have a look at the Config stream. It begins like follows, and goes on forever with various integer fields and other binary blobs.

(StorageContainer) [15] {
0 0x2090: (StorageRaw) {
Size: 4
String: ....
Hex: 00 00 00 00 }
1 0x20e0: (StorageContainer) [4] {
0 0x0100: (StorageRaw) {
Size: 12
String: .. A........
Hex: 00 00 20 41 0a 00 00 00 01 00 00 00 }
1 0x0400: (StorageRaw) {
Size: 8
String: ........
Hex: 07 00 00 00 01 00 00 00 }

As most of the contents seems fairly different from eachother, it's best to look from a distance to the main container.

(StorageContainer) [15] {
0 0x2090: (StorageRaw)
1 0x20e0: (StorageContainer) [4]
2 0x20a0: (StorageContainer) [2]
3 0x20a5: (StorageContainer) [2]
4 0x20a6: (StorageContainer) [1]
5 0x2190: (StorageContainer) [2]
6 0x20b0: (StorageContainer) [10]
7 0x2130: (StorageContainer) [3]
8 0x2080: (StorageContainer) [213]
9 0x20d0: (StorageContainer) [9]
10 0x2160: (StorageContainer) [5]
11 0x21a0: (StorageContainer) [82]
12 0x2180: (StorageContainer) [1]
13 0x2007: (StorageContainer) [1]
14 0x2008: (StorageContainer) [3] }

The first id seems to be unique, so we can assume that each of these containers has a specific set of information in it. Comparing between files of max versions, there are some less and some more of these identifiers, but the contents of them remains pretty much the same.

One container in this file particularly interests me, as it contains strings related to the NeL Material, and thus will likely be necessary to parse the Scene format where this is stored. More specifically, chunk 0x2180 contains stuff like the following:

9 0x0007: (StorageContainer) [3] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 02 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 17
String: ....bForceZWrite.
Hex: 0d 00 00 00 62 46 6f 72 63 65 5a 57 72 69 74 65 00 }
2 0x0007: (StorageContainer) [7] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 06 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 9
String: ....type.
Hex: 05 00 00 00 74 79 70 65 00 }
2 0x0006: (StorageRaw) {
Size: 12
String: ....boolean.
Hex: 08 00 00 00 62 6f 6f 6c 65 61 6e 00 }
...

The block itself begins like:

12 0x2180: (StorageContainer) [1] {
0 0x0040: (StorageContainer) [2] {
0 0x0050: (StorageRaw) {
Size: 12
String: ....._.d..+"
Hex: 00 0c 00 00 ec 5f c7 64 b9 9e 2b 22 }
1 0x0007: (StorageContainer) [10] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 09 00 00 00 }
1 0x0007: (StorageContainer) [15] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 0e 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 9
String: ....nlbp.
Hex: 05 00 00 00 6e 6c 62 70 00 }
...

A max file that has the NeL Multi Bitmap script used in it as well, has 2 0x0040 entries in the 0x2180 container. We'll call the 0x2180 block ConfigScript, and the 0x0040 container ConfigScriptEntry from now on, as these seem to be related to how script parameters will be stored in the file. What's also interesting is that all the chunks with id 0x0007 in this entire block are containers, and all the 0x0060 blocks are integers. The 0x0050 block is the header block for the ConfigScriptEntry, and contains the same SuperClassID and ClassID from the NeL Material script as seen previously.

Here are a few 0x0007 blocks from a specific depth inside the tree structure:

2 0x0007: (StorageContainer) [5] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 04 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 9
String: ....type.
Hex: 05 00 00 00 74 79 70 65 00 }
2 0x0006: (StorageRaw) {
Size: 12
String: ....boolean.
Hex: 08 00 00 00 62 6f 6f 6c 65 61 6e 00 }
3 0x0006: (StorageRaw) {
Size: 12
String: ....default.
Hex: 08 00 00 00 64 65 66 61 75 6c 74 00 }
4 0x0001: (StorageRaw) {
Size: 4
String: ....
Hex: 00 00 00 00 } } }
2 0x0007: (StorageContainer) [7] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 06 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 9
String: ....type.
Hex: 05 00 00 00 74 79 70 65 00 }
2 0x0006: (StorageRaw) {
Size: 10
String: ....float.
Hex: 06 00 00 00 66 6c 6f 61 74 00 }
3 0x0006: (StorageRaw) {
Size: 12
String: ....default.
Hex: 08 00 00 00 64 65 66 61 75 6c 74 00 }
4 0x0004: (StorageRaw) {
Size: 4
String: ..#<
Hex: 0a d7 23 3c }
5 0x0006: (StorageRaw) {
Size: 7
String: ....ui.
Hex: 03 00 00 00 75 69 00 }
6 0x0007: (StorageContainer) [2] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 01 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 17
String: ....cfBumpUSpeed.
Hex: 0d 00 00 00 63 66 42 75 6d 70 55 53 70 65 65 64 00 } } } }
2 0x0007: (StorageContainer) [5] {
0 0x0060: (StorageRaw) {
Size: 4
String: ....
Hex: 04 00 00 00 }
1 0x0006: (StorageRaw) {
Size: 9
String: ....type.
Hex: 05 00 00 00 74 79 70 65 00 }
2 0x0006: (StorageRaw) {
Size: 12
String: ....integer.
Hex: 08 00 00 00 69 6e 74 65 67 65 72 00 }
3 0x0006: (StorageRaw) {
Size: 12
String: ....default.
Hex: 08 00 00 00 64 65 66 61 75 6c 74 00 }
4 0x0003: (StorageRaw) {
Size: 4
String: ....
Hex: 01 00 00 00 } } }

If you have an understanding of the file format at this point, and try to understand the contents of these blocks, you should notice how ridiculous this looks.

It's like making an xml file that goes

<name>Name</name><value>Number</value>
<name>Value</name><value>2</value>

instead of

<Number>2</Number>

thanks to abstraction layers being piled up on each other.

The 0x0060 entry contains an integer which states the number of chunks that follow in the container, and is thus basically the size header of an array. Chunks with id 0x0006 recognizably contain strings, prefixed with their size, which is already known by the chunk header, and followed by an unnecessary null value byte suffix. It gets even sillier. The blocks shown above are actually not arrays, but tables of two columns stored in an array stored in the chunk tree structure. The first value in the array is the name column, and the second value the value column.

These blocks are child chunks of containers, containing a chunk with a name of a data field, and describe the format of this data field. It is fairly straightforward, the value of the name 'type' is the type, the 'default' is the default, and so on. For the default value, and this actually goes for the entire format of the ConfigScript block, the id of the chunk is directly related to the type field, and defines the actual low level storage of the field. The type fields is very helpful in finding out the meanings of these chunk ids.

0x0001 is a boolean stored as 4 bytes, 0x0002 does not appear in my file, 0x0003 is a 32 bit possibly signed integer, 0x0004 is a float, 0x0005 is a string in the same format as the 0x0006 internal strings, 0x0007 is the previously covered array-in-a-container, 0x0008 is a color stored as a 3 floating point vector with value 255.f being the maximum. With this information, the file can be made much more readable. Here's a short excerpt (pun intended) from inside the ConfigScript block.

2 0x0007: (ConfigScriptMetaContainer) [42] {
0 0x0060: (CStorageValue) { 41 }
1 0x0006: (ConfigScriptMetaString) { main }
2 0x0003: (CStorageValue) { 1 }
3 0x0003: (CStorageValue) { 2 }
4 0x0007: (ConfigScriptMetaContainer) [3] {
0 0x0060: (CStorageValue) { 2 }
1 0x0006: (ConfigScriptMetaString) { rollout }
2 0x0006: (ConfigScriptMetaString) { NelParams } }
5 0x0007: (ConfigScriptMetaContainer) [3] {
0 0x0060: (CStorageValue) { 2 }
1 0x0006: (ConfigScriptMetaString) { bLightMap }
2 0x0007: (ConfigScriptMetaContainer) [5] {
0 0x0060: (CStorageValue) { 4 }
1 0x0006: (ConfigScriptMetaString) { type }
2 0x0006: (ConfigScriptMetaString) { boolean }
3 0x0006: (ConfigScriptMetaString) { default }
4 0x0001: (CStorageValue) { 0 } } }
6 0x0007: (ConfigScriptMetaContainer) [3] {
0 0x0060: (CStorageValue) { 2 }
1 0x0006: (ConfigScriptMetaString) { bUnlighted }
2 0x0007: (ConfigScriptMetaContainer) [7] {
0 0x0060: (CStorageValue) { 6 }
1 0x0006: (ConfigScriptMetaString) { type }
2 0x0006: (ConfigScriptMetaString) { boolean }
3 0x0006: (ConfigScriptMetaString) { default }
4 0x0001: (CStorageValue) { 0 }
5 0x0006: (ConfigScriptMetaString) { ui }
6 0x0007: (ConfigScriptMetaContainer) [2] {
0 0x0060: (CStorageValue) { 1 }
1 0x0006: (ConfigScriptMetaString) { cbUnlighted } } } }
7 0x0007: (ConfigScriptMetaContainer) [3] {
0 0x0060: (CStorageValue) { 2 }
1 0x0006: (ConfigScriptMetaString) { bStainedGlassWindow }
2 0x0007: (ConfigScriptMetaContainer) [7] {
0 0x0060: (CStorageValue) { 6 }
1 0x0006: (ConfigScriptMetaString) { type }
2 0x0006: (ConfigScriptMetaString) { boolean }
3 0x0006: (ConfigScriptMetaString) { default }
4 0x0001: (CStorageValue) { 0 }
5 0x0006: (ConfigScriptMetaString) { ui }
6 0x0007: (ConfigScriptMetaContainer) [2] {
0 0x0060: (CStorageValue) { 1 }
1 0x0006: (ConfigScriptMetaString) { cbStainedGlassWindow } } } }

Most other blocks in this file seem to contain value sets where the type is fixed to the id, and the id is basically the name of the config value. Right now, there doesn't seem to be anything in there that interests me, so I won't bother with them too much, but here's an example of one simplified anyways.

2 0x20a0: (Config20a0) [2] {
0 0x0100: (CStorageValue) { 1 }
1 0x0110: (Config20a0Entry) [25] {
0 0x0100: (CStorageValue) { 220 }
1 0x0110: (CStorageValue) { 0 }
2 0x0120: (CStorageValue) { 1 }
3 0x0130: (CStorageValue) { 0 }
4 0x0140: (CStorageValue) { 0 }
5 0x0150: (CStorageValue) { 0 }
6 0x0160: (CStorageValue) { 1 }
7 0x0161: (CStorageValue) { 1 }
8 0x0170: (CStorageValue) { 1 }
9 0x0180: (CStorageValue) { 0 }
10 0x0190: (CStorageValue) { 0 }
11 0x0200: (CStorageValue) { 0 }
12 0x0210: (CStorageValue) { 0 }
13 0x0220: (CStorageValue) { 994352038 }
14 0x0230: (CStorageValue) { 1041059807 }
15 0x0240: (CStorageValue) { 266338296 }
16 0x0250: (CStorageValue) { 131008 }
17 0x0260: (CStorageValue) { 0 }
18 0x0270: (CStorageValue) { 1 }
19 0x0280: (CStorageValue) { 0 }
20 0x0310: (CStorageValue) { 0 }
21 0x0290: (CStorageValue) { }
22 0x0390: (CStorageValue) { default }
23 0x0300: (StorageContainer) [1] {
0 0x0100: (StorageRaw) {
Size: 4
String: ....
Hex: 00 00 00 00 } }
24 0x0330: (StorageRaw) {
Size: 16
String: ................ } } }

Quite boring, right?

Next up is the long awaited Scene.

【转】http://blog.kaetemi.be/post/2012/08/19/3ds-Max-File-Format-%28Part-3%29

3ds Max File Format (Part 3: The department of redundancy department; Config)的更多相关文章

  1. 3ds Max File Format (Part 1: The outer file format; OLE2)

    The 3ds Max file format, not too much documentation to be found about it. There are some hints here ...

  2. 3ds Max File Format (Part 5: How it all links together; ReferenceMaker, INode)

    At this point, you should start to familiarize yourself a bit with the publicly available 3ds Max AP ...

  3. 3ds Max File Format (Part 2: The first inner structures; DllDirectory, ClassDirectory3)

    Now that we understand the outer structure of the file, it's time to look closer to what's inside. T ...

  4. 3ds Max File Format (Part 4: The first useful data; Scene, AppData, Animatable)

    The most interesting part of this file is, evidently, the Scene. Opening it up in the chunk parser, ...

  5. 3ds Max File Format (Part 6: We get signal)

    Let's see what we can do now. INode *node = scene.container()->scene()->rootNode()->find(uc ...

  6. The Department of Redundancy Department

    Write a program that will remove all duplicates from a sequence of integers and print the list of un ...

  7. uva 484 - The Department of Redundancy Department

    已有的数据结构装不下数据,或者不能处理现有的数据,那就必须要思考其他的辅助手段,辅助结构: #include <cstdio> #include <map> #include ...

  8. AVEVA PDMS to 3ds Max - RvmTranslator6.0beta

    AVEVA PDMS to 3ds Max - RvmTranslator6.0beta eryar@163.com RvmTranslato6.0 translate PDMS RVM to 3ds ...

  9. VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人]

    VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人] 对最新版本的V ...

随机推荐

  1. 聊聊spring之贯穿全局的重要对象BeanDefinition

    BeanDefinition 在 spring 中贯穿始终,spring 要根据 BeanDefinition 对象来实 例化 bean,只要把解析的标签,扫描的注解类封装成 BeanDefiniti ...

  2. 【01】HTML_day01_01-前言&WEB标准

    typora-copy-images-to: media 第01阶段.前端基础.认识WEB 基础班学习目标 目标: 能根据psd文件,用HTML+CSS 布局出符合W3C规范的网页. 网站首页 列表页 ...

  3. 小白的linux笔记7:批量运行复杂的linux命令组合——BASH简单使用法

    linux的BASH就相当于windows下的BAT文件,可以批处理命令.比如写好一个python脚本后,需要在运行时候加参数,但这个参数又不想每次输入,就可以用BASH的方式写好整条命令,然后直接运 ...

  4. opencv —— HoughLines、HoughLinesP 霍夫线变换原理(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)及直线检测

    霍夫线变换的原理 一条直线在图像二维空间可由两个变量表示,有以下两种情况: ① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示. ② 在极坐标系中:可由参数极经和极角(r,θ)表示. 对于霍夫线变 ...

  5. GHM论文笔记(CVPR2019)

    目录 作者要解决的问题 Focal loss(CVPR2017) Focal loss的解决方案 Focal loss的不足 设计思路 梯度与样本的关系 梯度分布计算方法:将0-1的梯度切bin,计算 ...

  6. 清北学堂—2020.1提高储备营—Day 2 afternoon(线段树、树状数组)

    qbxt Day 2 afternoon --2020.1.18 济南 主讲:李佳实 目录一览 1.线段树 2.二叉搜索树(略过) 3.树状数组 总知识点:基础数据结构(本人初学感觉好难) 一.线段树 ...

  7. 有关css编写文字动态下划线

    <div class="main_text">哈哈这就是我的小视频</div> 上面为html代码 接下来进行css的编写 .main_text{ posi ...

  8. VMware与Centos系统安装之重置root密码

    VMware与Centos系统安装之重置root密码   今日任务 1.Linux发行版的选择 2.vmware创建一个虚拟机(centos) 3.安装配置centos7 4.xshell配置连接虚拟 ...

  9. PTA 汉诺塔的非递归实现(C 语言)

    借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c), 即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”), 并保证每个移动符合汉诺塔问题的要求 ...

  10. 使用vegrant安装centos7

    1.首先去安装需要先安装好 Vagrant 和 VirtualBox. 安装好需要重启电脑. 可能网速会很慢,建议复制链接到迅雷下载,或者国内随便找个下载也可以. 2.在电脑创建vagrant_vm目 ...