3DS file format

Source: Internet
Author: User
Tags fread

3DS file format

1. Read rules the 3ds file reading rules are as follows:

Bytes: read directly;

Word: Read the low byte first, and then read the high byte. For example, the word after reading the ed 3c is 3c ed;

Dual-text: Read the low-level text first, and then read the High-Level text. For example, the double-word after reading the ed 3c 25 43 is 43 25 3c ed;

Floating Point: read four bytes directly.

 

2. CHUNK

The chunk is the basic unit of the 3ds file. Each chunk includes a header and a subject. Chunk is nested with each other, which determines that you must read them recursively. The chunk header consists of two parts: the ID is a word, and the chunk length (in bytes, including the header) is a double character. ID indicates the meaning of chunk. In fact, there are thousands of chunks, which constitute a complex but flexible file system. You can read the entire file without knowing everything. The Chunks I have basically figured out are:

0x4D4D: Root chunk. Each 3ds file starts from it. Its length is the length of the file. It contains two chunks: the editor and the key frame.

Parent chunk: None

Sub-chunk: 0x3D3D, 0xB000

Length: Header Length + chunk Length

Content: None

 

0x3D3D: Editor master chunk, which contains grid information, lighting information, camera information, and material information.

Parent chunk: 0x4D4D

Sub-chunk: 0x4000, 0 xafff

Length: Header Length + chunk Length

Content: None

 

Zero x 4000: Grid master chunk, which contains all the grids.

Parent chunk: 0x3D3D

Sub-chunk: 0x4100

Length: Header Length + child chunk Length + content length

Content: Name (string ending with NULL bytes)

 

Zero x 4100: Grid information, including Grid names, vertices, faces, and texture coordinates.

Parent chunk: 0x4000

Sub-chunk: 0x4110, 0x4120, 0x4140, 0x4160

Length: Header Length + chunk Length

Content: None

 

Zero x 4110: Vertex information.

Parent chunk: 0x4100

Sub-chunk: None

Length: Header Length + content length

Content: Number of vertices (one word) vertex coordinates (three floating point numbers, one coordinate x, y, z, number x 3 * floating point numbers)

 

Zero x 4120: Surface information.

Parent chunk: 0x4100

Sub-chunk: 0x4130

Length: Header Length + child chunk Length + content length

Content: Number of faces (one word) vertex index (three words one index 1, 2, 3, Number * 3 * words)

 

Zero x 4130: Mesh-related material information.

Parent chunk: 0x4120

Sub-chunk: None

Length: Header Length + content length

Content: Name (string ending with an empty byte) Number of faces connected to the material (one word) index of the surface connected to the material (Number * word)

 

Zero x 4140: Texture coordinates.

Parent chunk: 0x4100

Sub-chunk: None

Length: Header Length + content length

Content: coordinates of the number of coordinates (one word) (two floating point numbers, one coordinate, u, v, and the number x 2 * floating point numbers)

 

Zero x 4160: Conversion matrix.

Parent chunk: 0x4100

Sub-chunk: None

Length: Header Length + content length

Content: X-axis vector (three floating point numbers u, v, n) Y-axis vector (three floating point numbers u, v, n) z axis vector (three floating point numbers u, v, n) Source coordinate (three floating point numbers x, y, z)

 

0 xafff: Material information.

Parent chunk: 0x4D4D

Sub-chunk: 0xa000, 0xa020, 0xa200

Length: Header Length + chunk Length

Content: None

 

0xa000: Material name.

Parent chunk: 0 xafff

Sub-chunk: None

Length: Header Length + content length

Content: Name (string ending with NULL bytes)

 

0xa020: Full shot.

Parent chunk: 0 xafff

Sub-chunk: 0x0011, 0x0012

Length: Header Length + chunk Length

Content: None

 

0xa200: Texture post image.

Parent chunk: 0 xafff

Sub-chunk: 0xa300

Length: Header Length + chunk Length

Content: None

 

0xa300: Post image name.

Parent chunk: 0xa200

Sub-chunk: None

Length: Header Length + content length

Content: Name (string ending with NULL bytes)

 

0xB000: The primary chunk of the key frame, which contains all key frame information.

Parent chunk: 0x4D4D

Sub-chunk: 0xB008, 0xB002

Length: Header Length + chunk Length

Content: None

 

0xB008: The start and end of the key frame.

Parent chunk: 0xB000

Sub-chunk: None

Length: Header Length + content length

Content: Start frame (one double character) end frame (one double character)

 

0xB002: Key frame information of the grid.

Parent chunk: 0xB000

Chunk: 0xB010, 0xB011, 0xB013, 0xB020, 0xB021, 0xB022, 0xB030

Length: Header Length + chunk Length

Content: None

 

0xB010: The level of the key frame, including the name and the index of the key frame at the upper level. The name is consistent with the name of the mesh to which the key frame points.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: Name (a string ending with a Null Byte) index of the first-level key frame on two unknown words (one word)

 

0xB011: The dummy name of the key frame. I don't know the specific meaning of dummy here, but as long as the name you read in the previous chunk is "$ DUMMY", you need to read its real name here. Because it points to a virtual group instead of a grid.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: Name (string ending with NULL bytes)

 

0xB013: Pivot coordinate.

Parent chunk: 0xB002

Sub-chunk: No length: Header Length + content length

Content: Three floating point numbers x, y, z

 

0xB020: Key frame information to be moved.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: The number of five unknown word frames (one word). There are so many loop structures each by one {frame index (one word) an unknown double-character moving vector (three floating point numbers x, y, z )}

 

0xB021: The information of the rotated key frame.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: The number of five unknown word frames (one word) A number of so many loop structures {frame index (one word) an unknown double-word rotation angle (one floating point number) the rotation vector (three floating point numbers x, y, z )}

 

0xB022: Key frame information for scaling.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: The number of five unknown word frames (one word). There are so many loop structures each by one {frame index (one word) an unknown double-word scaling vector (three floating point numbers x, y, z )}

 

0xB030: Key Frame index.

Parent chunk: 0xB002

Sub-chunk: None

Length: Header Length + content length

Content: Key Frame index (one word)

 

The following chunks may appear in any chunk:

 

Zero x 0010: The color of the floating point format.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: color (three floating point numbers red, green, blue)

 

Zero x 0011: The color of the byte format.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: color (three bytes red, green, blue)

 

Zero x 0012: Gamma Correction of the byte format.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: color (three bytes red, green, blue)

 

Zero x 0013: Gamma Correction of floating point format.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: color (three floating point numbers red, green, blue)

 

Zero x 0030: Percentage of the Word format.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: percentage (0 ~ 100)

 

Zero x 0031: Percentage of a floating point.

Parent chunk: any possible chunk

Sub-chunk: None

Length: Header Length + content length

Content: percentage (0 ~ 100)

 

3ds files are stored based on "blocks". These blocks describe data such as scenarios, the status of each edit window (Viewport), materials, and grid objects.
1. How to organize 3DS Blocks
MAIN3DS (0x4D4D) // basic information block
|
+ -- VERSION (0x0002) // VERSION information block
|
+ -- EDIT3DS (0x3D3D) // edit the information block
|
| + -- EDIT_MATERIAL (0 xAFFF) // Material
|
| + -- MAT_NAME01 (0xA000) // material name
| + -- MAT_AMBCOL (0xA010) // environment color
| + -- MAT_DIFCOL (0xA020) // diffuse color
| + -- MAT_SPECOL (0xA030) // reflection color
| + -- MAT_SHININESS (0xA040) // brightness
| + -- MATMAP (0xA200) // texture of the material ?????
| + -- MATMAPFILE (0xA300) // Save the texture file name
|
| + -- EDIT_CONFIG1 (0x0100) // configuration information 1
| + -- EDIT_CONFIG2 (0x3E3D) // configure information 2
| + -- EDIT_VIEW_P1 (0x7012) // window 1
|
| + -- TOP (0x0001) // TOP View
| + -- BOTTOM (0x0002) // BOTTOM view
| + -- LEFT (0x0003) // LEFT view
| + -- RIGHT (0x0004) // RIGHT view
| + -- FRONT (0x0005) // FRONT View
| + -- BACK (0x0006) // rear view
| + -- USER (0x0007) // USER-Defined
| + -- CAMERA (0 xFFFF) // CAMERA
| + -- LIGHT (0x0009) // LIGHT
| + -- DISABLED (0x0010) // disable
| + -- BOGUS (0x0011) // virtual
|
| + -- EDIT_VIEW_P2 (0x7011) // window 2
|
| + -- TOP (0x0001) // TOP View
| + -- BOTTOM (0x0002) // BOTTOM view
| + -- LEFT (0x0003) // LEFT view
| + -- RIGHT (0x0004) // RIGHT view
| + -- FRONT (0x0005) // FRONT View
| + -- BACK (0x0006) // rear view
| + -- USER (0x0007) // USER-Defined
| + -- CAMERA (0 xFFFF) // CAMERA
| + -- LIGHT (0x0009) // LIGHT
| + -- DISABLED (0x0010) // disable
| + -- BOGUS (0x0011) // virtual
|
| + -- EDIT_VIEW_P3 (0x7020) // window 3
| + -- EDIT_VIEW1 (0x7001) // View
| + -- EDIT_BACKGR (0x1200) // background
| + -- EDIT_AMBIENT (0x2100) // Environment
| + -- EDIT_OBJECT (0x4000) // object (including information such as surface and points)
|
| + -- OBJ_TRIMESH (0x4100) // Triangle Mesh object
|
| + -- TRI_VERTEX (0x4110) // Vertex
| + -- TRI_VERTEXOPTIONS (0x4111) // vertex options
| + -- TRI_MAPPINGCOORS (0x4140) // texture ing coordinates
| + -- TRI_MAPPINGSTANDARD (0x4170) // standard ing
| + -- TRI_FACEL1 (0x4120) // plane
| + -- TRI_SMOOTH (0x4150 )//
| + -- TRI_MATERIAL (0x4130) // material name
| + -- TRI_LOCAL (0x4160 )//
| + -- TRI_VISIBLE (0x4165) // visible or not
|
| + -- OBJ_LIGHT (0x4600) // light
|
| + -- LIT_OFF (0x4620)
| + -- LIT_SPOT (0x4610)
| + -- LIT_UNKNWN01 (0x0000a) // unknown Block
|
| + -- OBJ_CAMERA (0x4700)
|
| + -- CAM_UNKNWN01 (0x4710) // unknown Block
| + -- CAM_UNKNWN02 (0x4720) // unknown Block
|
| + -- OBJ_UNKNWN01 (0x4710) // unknown Block
| + -- OBJ_UNKNWN02 (0x4720) // unknown Block
|
| + -- EDIT_UNKNW01 (0x1100) // unknown Block
| + -- EDIT_UNKNW02 (0x1201) // unknown Block
| + -- EDIT_UNKNW03 (0x1300) // unknown Block
| + -- EDIT_UNKNW04 (0x1400) // unknown Block
| + -- EDIT_UNKNW05 (0x1420) // unknown Block
| + -- EDIT_UNKNW06 (0x1450) // unknown Block
| + -- EDIT_UNKNW07 (0x1500) // unknown Block
| + -- EDIT_UNKNW08 (0x2200) // unknown Block
| + -- EDIT_UNKNW09 (0x2201) // unknown Block
| + -- EDIT_UNKNW10 (0x2210) // unknown Block
| + -- EDIT_UNKNW11 (0x2300) // unknown Block
| + -- EDIT_UNKNW12 (0x2302) // unknown Block
| + -- EDIT_UNKNW13 (0x2000) // unknown Block
| + -- EDIT_UNKNW14 (0 xAFFF) // unknown Block
|
+ -- KEYF3DS (0xB000) // key frame information block
|
+ -- KEYF_UNKNWN01 (0xB00A) // unknown Block
+ -- EDIT_VIEW1 (0x7001) // View
+ -- KEYF_FRAMES (0xB008) // Frame
+ -- KEYF_UNKNWN02 (0xB009) // unknown Block
+ -- KEYF_OBJDES (0xB002) // Object Description ???
|
+ -- KEYF_OBJHIERARCH (0xB010) // level
+ -- KEYF_OBJDUMMYNAME (0xB011) // virtual body name
+ -- KEYF_OBJUNKNWN01 (0xB013) // unknown Block
+ -- KEYF_OBJUNKNWN02 (0xB014) // unknown Block
+ -- KEYF_OBJUNKNWN03 (0xB015) // unknown Block
+ -- KEYF_OBJTRANSLATE (0xB020) // offset
+ -- KEYF_OBJROTATE (0xB021) // rotate
+ -- KEYF_OBJSCALE (0xB022) // scale
In addition, some blocks often appear in the entire file, that is, color blocks.
COL_RGB 0x0010 // RGB color mode, which stores three components as float
COL_TRU 0x0011 // true color mode, which stores three parts in char
COL_UNKNOWN 0x0013 // unknown Block
SHI_PER 0x0030 // percentage brightness
In 3ds files, data is stored in Intel, that is to say, high is placed behind, and low is placed before. For example, the block ID of the Grid Object Block 0 x is stored at 00 40 in the file. For windows programmers, no conversion is required.
According to the 3ds file Division, one block is always located at the beginning of the entire file. It is the root block of all other blocks. We call it the main block or basic information block (MAIN3D block ). The main block contains two sub-blocks, which are the first-level sub-blocks: A Master editing block that describes the scene data and a key frame block that describes the key frame data. Compared with the key frame block, the master editing block is more important to us. It contains a series of data such as the materials used in the scenario (texture is a part of the material), configuration, the method of defining the view, the background color, and object data, it can be said that the current editing scenario and the configuration data of the current window are displayed.
Although the sub-blocks of the primary editing blocks are stored in a certain order, some of them do not exist (for example, if you do not define the material, use the default material, there will be no material blocks here ). The material block defines the attributes of materials used on objects, including: Material name, environment color, diffuse color, reflection color, brightness, texture of the material, and file name for saving the texture, the material name is a string, and the environmental, diffuse, and reflection colors are color blocks. Then there is a Grid Object block, which contains the geometric data of most of the objects we care about, as well as related information such as lights and cameras.
  
2. Data Structure and reading method of basic blocks
Each block contains a block header: The Block ID + block length, followed by the block header is the corresponding data. Take a basic block TRI_VERTEXL (0x4110) vertex block as an example.
It can be seen that the block header contains two items: ID and Size, which occupy a total of six digits. Size indicates the length of the entire block, rather than the data length. Pay attention to this. Therefore, the code for reading a vertex block can be written as follows:
ReadChunckHeader (& CH); // read the header information
Switch (CH. ChunckID) // determine the block type
{......
Case TRI_VERTEXL: // It is the vertex block of the object.
P3DObject-> NumVerts = ReadInt (); // obtain the total number of vertices.
P3DObject-> pVertices =: new CVertex [p3DObject-> NumVerts]; // allocate sufficient space
If (! P3DObject-> pVertices)
AfxMessageBox ("Error Allocating Memory ");
For (I = 0; I <p3DObject-> NumVerts; I ++) // read the 3D coordinate values of each vertex.
{
Fread (& p3DObject-> pVertices [I]. x, 4, 1, m_3dsFile );
Fread (& p3DObject-> pVertices [I]. y, 4, 1, m_3dsFile );
Fread (& p3DObject-> pVertices [I]. z, 4, 1, m_3dsFile );
}
}
The code to skip a block can be written as follows: (the two methods are equivalent)
Method 1: fseek (m_3dsFile,-6, SEEK_CUR); // 6 digits after the file pointer
Fseek (m_3dsFile, CH. ChunckSize, SEEK_CUR); // skip the block Length
Method 2: fseek (m_3dsFile, CH. ChunckSize-6, SEEK_CUR );
  
3. Hierarchical Structure of blocks and reading methods
The 3ds file format is not composed of some basic blocks, but a hierarchical structure. A basic block is required by a file and is at the top level, the main block includes the version information block, the editing information block, and the key frame information block. The level-1 block in the editing information block includes the material information block and the object information block. The second-level block in the object information block includes the Grid Object Information block, light information block, and camera information. The third-level information block in the Grid Object Information block includes vertex information, surface information, material name, And ing coordinates. Therefore, the 3ds file is a complex and ordered whole. If you start from the basic block, you have to draw the entire file, such a huge project leaves you with patience. Now, from EDIT_OBJECT, let's analyze the data reading problem in the Grid Object block.
Data22 is the data of the EDIT_OBJECT block. Size22 is equal to Data22 + 6 {Note: the ID number is int-type 2-bit, and Size22 is long-type 4-bit}. Data22 contains three-level sub-blocks, one third-level sub-block is OBJ_TRIMESH, corresponding data is Data31, and Size31 is equal to Data31 + 6. Similarly, Data31 contains a series of four-level sub-blocks, and TRI_VERTEX is one of them, TRI_VERTEX is a basic block and cannot be further subdivided. In Data41, coordinates of vertices are stored. For example, there are a total of 100 vertices in a grid object, and Data41 is equal to 100*4 = 400 bits {Note: The third-level coordinates of vertices are stored in float, so they are 4 bits }, therefore, Size41 equals to Data41 + 6 = 406, representing the length of the entire TRI_VERTEX {Note: including the ID number and Size41 itself }.
  


  
The block length number is set:
MAIN3DS (0x4D4D) Size00
|
+ -- VERSION (0x0002) Size11
+ -- EDIT3DS (0x3D3D) Size12
|
| + -- EDIT_MATERIAL (0 xAFFF) Size21
| + -- EDIT_OBJECT (0x4000) Size22
|
| + -- OBJ_TRIMESH (0x4100) Size31
|
| + -- TRI_VERTEX (0x4110) Size41
| + -- TRI_VERTEXOPTIONS (0x4111) Size42
| + --......
Therefore, if we want to read the vertex coordinates of the mesh object, we can use a switch block to judge it step by step, find the TRI_VERTEX block, and then read its data Data41 into our custom data structure.
ReadChunckHeader (& CH); // read the header information
Switch (CH. ChunckID) // determine the block type
{......
Case EDIT_OBJECT: // It is a Grid Object block.
ObjectName = ReadName (); // get the Object Name
ObjectFound = 2; // set the count to 2, which means to read the object's surface information and vertex information.
Success = true; // Success ID
Delete [] ObjectName; // clear the string for reading the next object
ObjectName = NULL;
Break; // read the next block out of the loop
Case TRI_VERTEXL: // It is the vertex block of the object.
If (ObjectFound) // The count is not 0.
{
ObjectFound --; // subtract one from the count
P3DObject-> NumVerts = ReadInt (); // obtain the total number of vertices.
P3DObject-> pVertices =: new CVertex [p3DObject-> NumVerts]; // allocate sufficient space
If (! P3DObject-> pVertices)
AfxMessageBox ("Error Allocating Memory ");
For (I = 0; I <p3DObject-> NumVerts; I ++) // read the 3D coordinate values of each vertex.
{
Fread (& p3DObject-> pVertices [I]. x, 4, 1, m_3dsFile );
Fread (& p3DObject-> pVertices [I]. y, 4, 1, m_3dsFile );
Fread (& p3DObject-> pVertices [I]. z, 4, 1, m_3dsFile );
}
}
When the else // count is 0, This vertex block will be skipped. The method for skipping a basic block is described in the previous section.
{
Fseek (m_3dsFile,-6, SEEK_CUR );
Fseek (m_3dsFile, CH. ChunckSize, SEEK_CUR );
}
Break; // read the next block out of the loop
......
}
  
Conclusion: Although Autodesk has not published an official 3ds file, according to the information collected on the internet, we can fully read the data we care about into a custom data structure, and then draw it out using the powerful graphics function library of OpenGL. The above is an entry-level document, which only gives a brief introduction to its principle and data block reading. If you have higher requirements, refer to the following documents:
[1] 3DS file structure (. 3ds) by Martin van Velsen
[2] The Unofficial 3 DStudio 3DS File Format by Jeff Lewis
[3] importing grid data from 3DS files-Author: Hometown cloud
Xiao Jianqing
2006.5.25 Yuanda

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.