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文件结构的信息的时候,我将重写这篇文档。
这篇文档描述了由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: vvelsen@ronix.ptf.hro.nl
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: vvelsen@ronix.ptf.hro.nl
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Ó~„gw4Y'YJU
ÿ_@wWinHex