3DS文件结构

https://blog.csdn.net/yaokang522/article/details/7306767

   3DS文件结构(.3ds)

文档版本:0.93 – 1997.1

作者:Martin vanVelsen(重写)

      Robin Fercoq(重写)

      Jim Pitts(原版)

      Albert Szilvasy(原代码)

翻译:樱

From:GameRes http://www.gameres.com

还有许多“块”我并没有写入本文档中,这是因为我并不知道他们有什么用,如果你知道的话请来信告诉我。当我获得更多关于3ds文件结构的信息的时候,我将重写这篇文档。

扫描二维码关注公众号,回复: 2931220 查看本文章

这篇文档描述了由AutoDesk公司的3dsmax产生的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 coderead 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字节组成(unsignedlong X 2),开始4个字节描述了开始帧,最后4个字节描述了结束帧。

B002物体信息块:

      ID        描述

 B010     名称与层次结构

    B011*   哑元物体命名(译者:也就是不在场景中显示的对象,一般用来对对象分组)

    B013     unknown

    B014*    unknown

 B015      unknown

    B020     物体转轴(中心点)

B021      unknown

    B022     unknown

B010名称与层次结构块:

该块由一个以0结尾的字符串开始,中间4个字节(unsignedshort 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

5.代码

说明!这些代码在他们写在本文档的0.9版后并没有升级。这些代码会在我有时间时升级,或者你有时间的话(译者:各位不必担心,本人已经写了一个简单的代码了,只是很乱)。如果这些代码看起来像是写在12年前的话,那么你上当了。我喜欢非常简单的读取代码。这些事情看起来就像是一个诡计!

/*----------------------------------------------------------------------------*\

     This is a lib which reads3d-studio binary files from version 3.0

     and higher

     (v1.05)

     author: Martin van Velsen

             ( and some greathelp by Gert van der Spoel )

     email:  [email protected]

     If you happen to comeacross some variables with strange names, then

     that will possible beDutch names, sorry for that :)

\*----------------------------------------------------------------------------*/

#ifndef __3DSBIN_H__

#define __3DSBIN_H__

#include <stdio.h

#include <string.h

#include <stdlib.h

#include <conio.h   // IFyou are on a dos system

#include <dos.h     // IFyou are on a dos system

//------ tools

#define __DEBUG__          0

#define TRUE               0

#define FALSE              1

//------ Id Chunk

#define MAIN3DS       0x4D4D

//------ Main Chunks

#define EDIT3DS      0x3D3D  // this is the start ofthe editor config

#define KEYF3DS      0xB000  // this is the start ofthe keyframer config

//------ sub defines of EDIT3DS

#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// new chunk type

#define EDIT_UNKNW13  0x3000

#define EDIT_UNKNW14  0xAFFF

//------ sub defines of EDIT_MATERIAL

#define MAT_NAME01   0xA000  // includes name (see mlidoc for materials)

//------ sub defines of EDIT_OBJECT

#define OBJ_TRIMESH   0x4100

#define OBJ_LIGHT     0x4600

#define OBJ_CAMERA    0x4700

#define OBJ_UNKNWN01  0x4010

#define OBJ_UNKNWN02  0x4012//---- Could be shadow

//------ sub defines of OBJ_CAMERA

#define CAM_UNKNWN01  0x4710// new chunk type

#define CAM_UNKNWN02  0x4720// new chunk type

//------ sub defines of OBJ_LIGHT

#define LIT_OFF       0x4620

#define LIT_SPOT      0x4610

#define LIT_UNKNWN01  0x465A

//------ sub defines of OBJ_TRIMESH

#define TRI_VERTEXL   0x4110

#define TRI_FACEL2    0x4111// unknown yet

#define TRI_FACEL1    0x4120

#define TRI_SMOOTH    0x4150

#define TRI_LOCAL     0x4160

#define TRI_VISIBLE   0x4165

//------ sub defs of KEYF3DS

#define KEYF_UNKNWN01 0xB009

#define KEYF_UNKNWN02 0xB00A

#define KEYF_FRAMES   0xB008

#define KEYF_OBJDES   0xB002

#define KEYF_OBJHIERARCH 0xB010

#define KEYF_OBJDUMMYNAME 0xB011

#define KEYF_OBJUNKNWN01 0xB013

#define KEYF_OBJUNKNWN02 0xB014

#define KEYF_OBJUNKNWN03 0xB015 

#define KEYF_OBJPIVOT    0xB020 

#define KEYF_OBJUNKNWN04 0xB021 

#define KEYF_OBJUNKNWN05 0xB022 

//------  these define thedifferent color chunk types

#define COL_RGB  0x0010

#define COL_TRU  0x0011

#define COL_UNK  0x0013 //unknown

//------ defines for viewport chunks

#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 code read from file

#define LIGHT         0x0009

#define DISABLED      0x0010

#define BOGUS         0x0011

//------ global vars

char *viewports [11]={

                      "Bogus",

                     "Top",

                     "Bottom",

                     "Left",

                     "Right",

                     "Front",

                     "Back",

                     "User",

                      "Camera",

                     "Light",

                     "Disabled"

                     };

FILE *bin3ds;

unsigned long current_chunk=0L;

unsigned char views_read=0;

unsigned int numb_faces=0,numb_vertices=0;

char temp_name [100];

float trans_mat [4][4]; // translation matrix for objects

#endif

-----------------------------8< cuthere  >8-------------------------------

/*----------------------------------------------------------------------------*\

     This is a lib which reads3d-studio binary files from version 3.0

     and higher

     (v1.05)

     author: Martin van Velsen

             ( and some greathelp by Gert van der Spoel )

     email:  [email protected]

     If you happen to comeacross some variables with strange names, then

     that will possible be Dutch names, sorryfor that :)

\*----------------------------------------------------------------------------*/

#ifndef __3DSBIN_C__

#define __3DSBIN_C__

#include "3ds_bin.h"

/*----------------------------------------------------------------------------*/

unsigned char ReadChar (void)

{

 return (fgetc (bin3ds));

 //------ if you want to addsome code to create a progress bar, then

 //------ I suggest you do ithere. This is the only function which

 //------ reads from disk

}

/*----------------------------------------------------------------------------*/

unsigned int ReadInt (void)

{

 unsigned int temp =ReadChar();

 return ( temp | (ReadChar ()<< 8));

}

/*----------------------------------------------------------------------------*/

unsigned long ReadLong (void)

{

 unsigned long temp1,temp2;

 unsigned long temp3,temp4;

 temp1=ReadInt ();

 temp2=ReadInt ();

 return(temp3+(temp4*0x10000L));

}

/*----------------------------------------------------------------------------*/

unsigned long ReadChunkPointer (void)

{

 return (ReadLong ());

}

/*----------------------------------------------------------------------------*/

unsigned long GetChunkPointer (void)

{

 return (ftell (bin3ds)-2); //compensate for the already read Marker

}

/*----------------------------------------------------------------------------*/

void ChangeChunkPointer (unsigned long temp_pointer)

{

 fseek(bin3ds,temp_pointer,SEEK_SET);

}

/*----------------------------------------------------------------------------*/

int ReadName (void)

{

 unsigned int teller=0;

 unsigned char letter;

 strcpy(temp_name,"Default name");

 letter=ReadChar ();

 if (letter==0) return (-1);// dummy object

 temp_name [teller]=letter;

 teller++;

 do

 {

  letter=ReadChar ();

  temp_name [teller]=letter;

  teller++;

 }

 while ((letter!=0) &&(teller<12));

 temp_name [teller-1]=0;

 #ifdef __DEBUG__

  printf ("     Found name : %s\n",temp_name);

 #endif

 return (0);

}

/*----------------------------------------------------------------------------*/

int ReadLongName (void)

{

 unsigned int teller=0;

 unsigned char letter;

 strcpy(temp_name,"Default name");

 letter=ReadChar ();

 if (letter==0) return (-1);// dummy object

 temp_name [teller]=letter;

 teller++;

 do

 {

  letter=ReadChar ();

  temp_name [teller]=letter;

  teller++;

 }

 while (letter!=0);

 temp_name [teller-1]=0;

 #ifdef __DEBUG__

   printf ("Found name :%s\n",temp_name);

 #endif

 return (0);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadUnknownChunk (unsigned int chunk_id)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 chunk_id=chunk_id;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadRGBColor (void)

{

 float rgb_val [3];

 for (int i=0;i<3;i++)

  fread (&(rgb_val [i]),sizeof(float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("     Found Color (RGB) def of:R:%5.2f,G:%5.2f,B:%5.2f\n",

          rgb_val [0],

          rgb_val [1],

          rgb_val [2]);

 #endif

 return (12L);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadTrueColor (void)

{

 unsigned char true_c_val [3];

 for (int i=0;i<3;i++)

  true_c_val [i]=ReadChar ();

 #ifdef __DEBUG__

 printf ("     Found Color (24bit) def of:R:%d,G:%d,B:%d\n",

          true_c_val [0],

          true_c_val [1],

          true_c_val [2]);

 #endif

 return (3L);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadBooleanChunk (unsigned char *boolean)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 *boolean=ReadChar ();

 ChangeChunkPointer(current_pointer+temp_pointer); // move to the new chunk position

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadSpotChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 float target [4];

 float hotspot,falloff;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 fread (&(target[0]),sizeof (float),1,bin3ds);

 fread (&(target[1]),sizeof (float),1,bin3ds);

 fread (&(target[2]),sizeof (float),1,bin3ds);

 fread (&hotspot,sizeof(float),1,bin3ds);

 fread (&falloff,sizeof(float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("      The target of the spot is at: X:%5.2fY:%5.2f Y:%5.2f\n",

          target [0],

          target [1],

          target [2]);

 printf ("      The hotspot of this light is :%5.2f\n",hotspot);

 printf ("      The falloff of this light is :%5.2f\n",falloff);

 #endif

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadLightChunk (void)

{

 unsigned charend_found=FALSE,boolean;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;// 2 id + 4 pointer

 float light_coors [3];

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 fread (&(light_coors[0]),sizeof (float),1,bin3ds);

 fread (&(light_coors[1]),sizeof (float),1,bin3ds);

 fread (&(light_coors[2]),sizeof (float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("     Found light at coordinates: X: %5.2f, Y:%5.2f,Z: %5.2f\n",

          light_coors [0],

          light_coors [1],

          light_coors [2]);

 #endif

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case LIT_UNKNWN01 :

                           #ifdef __DEBUG__

                          printf (" Found Light unknown chunk id of%0X\n",LIT_UNKNWN01);

                          #endif

                          tellertje+=ReadUnknownChunk (LIT_UNKNWN01);

                           break;

        case LIT_OFF      :

                          #ifdef __DEBUG__

                          printf (" Light is (on/off) chunk: %0X\n",LIT_OFF);

                          #endif

                          tellertje+=ReadBooleanChunk (&boolean);

                          #ifdef __DEBUG__

                           if(boolean==TRUE)

                            printf ("      Light ison\n");

                          else

                            printf ("      Light isoff\n");

                           #endif

                          break;

        case LIT_SPOT     :

                          #ifdef __DEBUG__

                          printf (" Light is SpotLight: %0X\n",TRI_VERTEXL);

                          #endif

                           tellertje+=ReadSpotChunk ();

                          break;

        case COL_RGB      :

                          #ifdef __DEBUG__

                          printf (" Found Color def (RGB) chunk id of %0X\n",temp_int);

                           #endif

                          tellertje+=ReadRGBColor ();

                          break;

        case COL_TRU      :

                          #ifdef __DEBUG__

                          printf (" Found Color def (24bit) chunk id of %0X\n",temp_int);

                          #endif

                          tellertje+=ReadTrueColor ();

                          break;

        default           :break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadCameraChunk (void)

{

 unsigned long current_pointer;

 unsigned long temp_pointer;

 float camera_eye [3];

 float camera_focus [3];

 float rotation,lens;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 fread (&(camera_eye[0]),sizeof (float),1,bin3ds);

 fread (&(camera_eye[1]),sizeof (float),1,bin3ds);

 fread (&(camera_eye[2]),sizeof (float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("     Found Camera viewpoint at coordinates: X:%5.2f, Y: %5.2f,Z: %5.2f\n",

          camera_eye [0],

          camera_eye [1],

          camera_eye [2]);

 #endif

 fread (&(camera_focus[0]),sizeof (float),1,bin3ds);

 fread (&(camera_focus[1]),sizeof (float),1,bin3ds);

 fread (&(camera_focus[2]),sizeof (float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("     Found Camera focus coors at coordinates:X: %5.2f, Y: %5.2f,Z: %5.2f\n",

          camera_focus [0],

          camera_focus [1],

          camera_focus [2]);

 #endif

 fread (&rotation,sizeof(float),1,bin3ds);

 fread (&lens,sizeof(float),1,bin3ds);

 #ifdef __DEBUG__

 printf ("     Rotation of camera is:  %5.4f\n",rotation);

 printf ("     Lens in used camera is:%5.4fmm\n",lens);

 #endif

 if ((temp_pointer-38)0) //this means more chunks are to follow

 {

  #ifdef __DEBUG__

  printf ("     **** found extra cam chunks ****\n");

  #endif

  if (ReadInt()==CAM_UNKNWN01)

  {

   #ifdef __DEBUG__

   printf ("     **** Found cam 1 type ch ****\n");

   #endif

   ReadUnknownChunk(CAM_UNKNWN01);

  }

  if (ReadInt()==CAM_UNKNWN02)

  {

   #ifdef __DEBUG__

   printf ("     **** Found cam 2 type ch ****\n");

   #endif

   ReadUnknownChunk(CAM_UNKNWN02);

  }

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadVerticesChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 float vertices [3]; // x,y,z

 unsigned int numb_v;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 numb_vertices  =ReadInt ();

 #ifdef __DEBUG__

 printf ("      Found (%d) number ofvertices\n",numb_vertices);

 #endif

 for (inti=0;i<numb_vertices;i++)

 {

  fread (&(vertices[0]),sizeof (float),1,bin3ds);

  fread (&(vertices[1]),sizeof (float),1,bin3ds);

  fread (&(vertices [2]),sizeof(float),1,bin3ds);

  #ifdef __DEBUG__

  printf ("      Vertex nr%4d: X: %5.2f  Y: %5.2f Z:%5.2f\n",

           i,

           vertices [0],

           vertices [1],

           vertices [2]);

  #endif

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadSmoothingChunk ()

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long smoothing;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 for (inti=0;i<numb_faces;i++)

 {

  smoothing=ReadLong();

  smoothing=smoothing; //compiler warnig depressor *:)

  #ifdef __DEBUG__

  printf ("      The smoothing group for face [%5d] is%d\n",i,smoothing);

  #endif

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadFacesChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned int temp_diff;

 unsigned int faces [6]; //a,b,c,Diff (Diff= AB: BC: CA: )

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 numb_faces     =ReadInt ();

 #ifdef __DEBUG__

 printf ("      Found (%d) number offaces\n",numb_faces);

 #endif

 for (inti=0;i<numb_faces;i++)

 {

  faces [0]=ReadInt ();

  faces [1]=ReadInt ();

  faces [2]=ReadInt ();

  temp_diff=ReadInt () &0x000F;

  faces [3]=(temp_diff &0x0004)  2;

  faces [4]=(temp_diff &0x0002)  1;

  faces [5]=(temp_diff &0x0001);

  #ifdef __DEBUG__

  printf ("      Face nr:%d, A: %d  B: %d C:%d , AB:%d  BC:%d  CA:%d\n",

           i,

           faces [0],

           faces [1],

           faces [2],

           faces [3],

           faces [4],

           faces [5]);

  #endif

 }

 if (ReadInt ()==TRI_SMOOTH)

  ReadSmoothingChunk ();

 #ifdef __DEBUG__

 else

  printf ("      No smoothing groups found, assumingautosmooth\n");

 #endif

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadTranslationChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 for (int j=0;j<4;j++)

 {

   for (int i=0;i<3;i++)

    fread (&(trans_mat[j][i]),sizeof (float),1,bin3ds);

 }

 trans_mat [0][3]=0;

 trans_mat [1][3]=0;

 trans_mat [2][3]=0;

 trans_mat [3][3]=1;

 #ifdef __DEBUG__

 printf ("     The translation matrix is:\n");

 for (int i=0;i<4;i++)

     printf ("      | %5.2f %5.2f %5.2f %5.2f |\n",

              trans_mat[i][0],

              trans_mat [i][1],

              trans_mat[i][2],

              trans_mat[i][3]);

 #endif

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadObjChunk (void)

{

 unsigned charend_found=FALSE,boolean=TRUE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;// 2 id + 4 pointer

 current_pointer=GetChunkPointer();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case TRI_VERTEXL :

                         #ifdef __DEBUG__

                          printf (" Found Object vertices chunk idof %0X\n",

                                 temp_int);

                         #endif

                         tellertje+=ReadVerticesChunk ();

                         break;

        case TRI_FACEL1  :

                          #ifdef __DEBUG__

                         printf (" Found Object faces (1) chunk id of %0X\n",

                                 temp_int);

                         #endif

                         tellertje+=ReadFacesChunk ();

                          break;

        case TRI_FACEL2  :

                         #ifdef __DEBUG__

                         printf (" Found Object faces (2) chunk id of %0X\n",

                                 temp_int);

                         #endif

                         tellertje+=ReadUnknownChunk (temp_int);

                         break;

        case TRI_LOCAL  :

                         #ifdef __DEBUG__

                         printf (" Found Object translation chunk id of %0X\n",

                                  temp_int);

                         #endif

                         tellertje+=ReadTranslationChunk ();

                         break;

        case TRI_VISIBLE :

                         #ifdef __DEBUG__

                          printf (" Found Object vis/invischunk id of %0X\n",

                                 temp_int);

                         #endif

                         tellertje+=ReadBooleanChunk (&boolean);

                         #ifdef __DEBUG__

                          if (boolean==TRUE)

                            printf ("      Object is(visible)\n");

                          else

                            printf ("      Object is (notvisible)\n");

                         #endif

                          break;

        default:          break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadObjectChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;// 2 id + 4 pointer

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 if (ReadName ()==-1)

 {

  #ifdef __DEBUG__

  printf ("* Dummy Objectfound\n");

  #endif

 }

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        caseOBJ_UNKNWN01:tellertje+=ReadUnknownChunk (OBJ_UNKNWN01);break;

        caseOBJ_UNKNWN02:tellertje+=ReadUnknownChunk (OBJ_UNKNWN02);break;

        case OBJ_TRIMESH :

                         #ifdef __DEBUG__

                          printf (" Found Obj/Meshchunk id of %0X\n",

                                 OBJ_TRIMESH);

                         #endif

                         tellertje+=ReadObjChunk ();

                         break;

        case OBJ_LIGHT   :

                         #ifdef __DEBUG__

                         printf (" Found Light chunk id of %0X\n",

                                 OBJ_LIGHT);

                         #endif

                         tellertje+=ReadLightChunk ();

                          break;

        case OBJ_CAMERA  :

                         #ifdef __DEBUG__

                         printf (" Found Camera chunk id of %0X\n",

                                 OBJ_CAMERA);

                         #endif

                          tellertje+=ReadCameraChunk ();

                         break;

        default:          break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadBackgrChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned long current_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;// 2 id + 4 pointer

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case COL_RGB :

                      #ifdef__DEBUG__

                      printf(" Found Color def (RGB) chunk id of %0X\n",

                             temp_int);

                      #endif

                     tellertje+=ReadRGBColor ();

                      break;

        case COL_TRU :

                      #ifdef__DEBUG__

                      printf(" Found Color def (24bit) chunk id of %0X\n",

                             temp_int);

                      #endif

                      tellertje+=ReadTrueColor();

                      break;

        default:      break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadAmbientChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;// 2 id + 4 pointer

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case COL_RGB :

                      #ifdef __DEBUG__

                      printf(" Found Color def (RGB) chunk id of %0X\n",

                             temp_int);

                      #endif

                     tellertje+=ReadRGBColor ();

                      break;

        case COL_TRU :

                      #ifdef__DEBUG__

                      printf(" Found Color def (24bit) chunk id of %0X\n",

                             temp_int);

                      #endif

                     tellertje+=ReadTrueColor ();

                      break;

        default:      break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long FindCameraChunk (void)

{

 long temp_pointer=0L;

 for (int i=0;i<12;i++)

  ReadInt ();

 temp_pointer=11L;

 temp_pointer=ReadName ();

 #ifdef __DEBUG__

 if (temp_pointer==-1)

   printf ("* No Cameraname found\n");

 #endif

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadViewPortChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned int port,attribs;

 views_read++;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 attribs=ReadInt ();

 if (attribs==3)

 {

  #ifdef __DEBUG__

  printf ("<Snap> active in viewport\n");

  #endif

 }

 if (attribs==5)

 {

  #ifdef __DEBUG__

  printf ("<Grid> active in viewport\n");

  #endif

 }

 for (int i=1;i<6;i++)ReadInt (); // read 5 ints to get to the viewport

 port=ReadInt ();

 if ((port==0xFFFF) ||(port==0))

 {

   FindCameraChunk ();

   port=CAMERA;

 }

 #ifdef __DEBUG__

 printf ("Reading [%s]information with id:%d\n",viewports [port],port);

 #endif

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadViewChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case EDIT_VIEW_P1 :

                          #ifdef __DEBUG__

                          printf (" Found Viewport1 chunk id of %0X\n",

                                  temp_int);

                          #endif

                          tellertje+=ReadViewPortChunk ();

                          break;

        case EDIT_VIEW_P2 :

                          #ifdef __DEBUG__

                          printf (" Found Viewport2 (bogus) chunk id of %0X\n",

                                  temp_int);

                          #endif

                          tellertje+=ReadUnknownChunk (EDIT_VIEW_P2);

                           break;

       case EDIT_VIEW_P3 :

                          #ifdef __DEBUG__

                          printf (" Found Viewport chunk id of %0X\n",

                                  temp_int);

                          #endif

                           tellertje+=ReadViewPortChunk ();

                          break;

        default           :break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

   if (views_read3)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadMatDefChunk (void)

{

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 if (ReadLongName ()==-1)

 {

   #ifdef __DEBUG__

   printf ("* No Materialname found\n");

   #endif

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadMaterialChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned long current_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case MAT_NAME01  :

                         #ifdef __DEBUG__

                         printf (" Found Material def chunk id of %0X\n",

                                 temp_int);

                         #endif

                         tellertje+=ReadMatDefChunk ();

                         break;

        default:break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadEditChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        caseEDIT_UNKNW01:tellertje+=ReadUnknownChunk (EDIT_UNKNW01);break;

        caseEDIT_UNKNW02:tellertje+=ReadUnknownChunk (EDIT_UNKNW02);break;

        caseEDIT_UNKNW03:tellertje+=ReadUnknownChunk (EDIT_UNKNW03);break;

        caseEDIT_UNKNW04:tellertje+=ReadUnknownChunk (EDIT_UNKNW04);break;

        caseEDIT_UNKNW05:tellertje+=ReadUnknownChunk (EDIT_UNKNW05);break;

        caseEDIT_UNKNW06:tellertje+=ReadUnknownChunk (EDIT_UNKNW06);break;

        caseEDIT_UNKNW07:tellertje+=ReadUnknownChunk (EDIT_UNKNW07);break;

        caseEDIT_UNKNW08:tellertje+=ReadUnknownChunk (EDIT_UNKNW08);break;

        caseEDIT_UNKNW09:tellertje+=ReadUnknownChunk (EDIT_UNKNW09);break;

        caseEDIT_UNKNW10:tellertje+=ReadUnknownChunk (EDIT_UNKNW10);break;

        caseEDIT_UNKNW11:tellertje+=ReadUnknownChunk (EDIT_UNKNW11);break;

        caseEDIT_UNKNW12:tellertje+=ReadUnknownChunk (EDIT_UNKNW12);break;

        caseEDIT_UNKNW13:tellertje+=ReadUnknownChunk (EDIT_UNKNW13);break;

        case EDIT_MATERIAL :

                           #ifdef __DEBUG__

                           printf (" Found Materials chunk id of %0X\n",

                                   temp_int);

                           #endif

                           tellertje+=ReadMaterialChunk ();

                           break;

        case EDIT_VIEW1    :

                            #ifdef __DEBUG__

                           printf (" Found View main def chunk id of %0X\n",

                                   temp_int);

                           #endif

                           tellertje+=ReadViewChunk ();

                            break;

        case EDIT_BACKGR   :

                           #ifdef __DEBUG__

                           printf (" Found Backgr chunk id of %0X\n",

                                   temp_int);

                           #endif

                            tellertje+=ReadBackgrChunk();

                           break;

        case EDIT_AMBIENT  :

                           #ifdef __DEBUG__

                           printf (" Found Ambient chunk id of %0X\n",

                                    temp_int);

                           #endif

                           tellertje+=ReadAmbientChunk ();

                           break;

        case EDIT_OBJECT   :

                           #ifdef __DEBUG__

                            printf (" Found Object chunk id of%0X\n",

                                   temp_int);

                           #endif

                           tellertje+=ReadObjectChunk ();

                           break;

        default:            break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadKeyfChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;

 current_pointer=GetChunkPointer ();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case KEYF_UNKNWN01:tellertje+=ReadUnknownChunk (temp_int);break;

        case KEYF_UNKNWN02:tellertje+=ReadUnknownChunk (temp_int);break;

        case KEYF_FRAMES   :

                           #ifdef __DEBUG__

                           printf (" Found Keyframer frames chunk id of %0X\n",

                                   temp_int);

                           #endif

                            tellertje+=ReadUnknownChunk(temp_int);

                           break;

        case KEYF_OBJDES   :

                           #ifdef __DEBUG__

                           printf (" Found Keyframer object description chunk id of%0X\n",

                                   temp_int);

                           #endif

                           tellertje+=ReadUnknownChunk (temp_int);

                           break;

        case EDIT_VIEW1    :

                           #ifdef __DEBUG__

                           printf (" Found View main def chunk id of %0X\n",

                                   temp_int);

                           #endif

                           tellertje+=ReadViewChunk ();

                           break;

        default:            break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

     end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

unsigned long ReadMainChunk (void)

{

 unsigned charend_found=FALSE;

 unsigned int temp_int;

 unsigned longcurrent_pointer;

 unsigned long temp_pointer;

 unsigned long tellertje=6L;

 current_pointer=GetChunkPointer();

 temp_pointer   =ReadChunkPointer ();

 while (end_found==FALSE)

 {

   temp_int=ReadInt ();

       switch (temp_int)

       {

        case KEYF3DS :

                      #ifdef__DEBUG__

                      printf(" Found *Keyframer* chunk id of %0X\n",KEYF3DS);

                      #endif

                     tellertje+=ReadKeyfChunk ();

                      break;

        case EDIT3DS :

                      #ifdef__DEBUG__

                      printf(" Found *Editor* chunk id of %0X\n",EDIT3DS);

                      #endif

                     tellertje+=ReadEditChunk ();

                      break;

        default:      break;

       }

   tellertje+=2;

   if (tellertje=temp_pointer)

    end_found=TRUE;

 }

 ChangeChunkPointer(current_pointer+temp_pointer);

 // move to the new chunkposition

 return (temp_pointer);

}

/*----------------------------------------------------------------------------*/

int ReadPrimaryChunk (void)

{

 unsigned char version;

 if (ReadInt ()==MAIN3DS)

 {

  #ifdef __DEBUG__

  printf (" Found Mainchunk id of %0X\n",MAIN3DS);

  #endif

  //---------- find versionnumber

  fseek (bin3ds,28L,SEEK_SET);

  version=ReadChar ();

  if (version<3)

  {

   #ifdef __DEBUG__

   printf ("Sorry thislib can only read 3ds files of version 3.0 and higher\n");

   printf ("The versionof the file you want to read is: %d\n",version);

   #endif

   return (1);

  }

  fseek (bin3ds,2,SEEK_SET);

  ReadMainChunk ();

 }

 else

  return (1);

 return (0);

}

/*----------------------------------------------------------------------------*/

/*                      TestMain for the 3ds-bin lib                        */

/*----------------------------------------------------------------------------*/

int main (int argc,char **argv)

{

 argc=argc;

 bin3ds=fopen (argv[1],"rb");

 if (bin3ds==NULL)

  return (-1);

 #ifdef __DEBUG__

  printf ("\nLoading 3dsbinary file : %s\n",argv [1]);

 #endif

 while (ReadPrimaryChunk()==0);

 return (0);

}

/*----------------------------------------------------------------------------*/

#endif

Ñ‹„vÝ‹ÿ

    }Y•„v‡eàz
ÿÈ~N‑dš[†N[1]0vQ-NY„vN›NŸ^Ý‹,gºN¡l      gûÑ‹
ÿæSYdk‡e-N       gY


YYNåwS„v0W¹eÿUNKNOWN ÿ
ÿ«ƒ^—©‹beg™Q­ÿÿD g
TY„vãNx<ONNˆ_•
ÿ4Y'Y„vˆ_
ÿ


TMO
w@w»æp„vÝ‹1\
wb™Q„vãNx'T
ÿ(W,gÙz
N     g[1]0xvz3DS‡eöNÓ~„g­w4Y'YJU
ÿ_@wWinHex

猜你喜欢

转载自blog.csdn.net/wang13342322203/article/details/81739612