DZB
DZB is used as the collision format in The Legend of Zelda: The Wind Waker. It was first introduced in The Legend of Zelda: The Wind Waker, and was mostly replaced by The Legend of Zelda: Twilight Princess, where it was only used for object collision, rather than scene collision.
The format contains no specific MAGIC, so its extension, ".dzb," is used to refer to it instead. DZB utilizes an embedded octree to accelerate collision detection by the engine and increase collision resolution.
Contents
File Header
The header of the DZB format lays out the offset of each section and the number of entries each of them has.
Size: 0x34 bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Vertices Count | |
|
|
Vertices Offset | |
|
|
Triangles Count | |
|
|
Triangles Offset | |
|
|
Blocks Count | |
|
|
Blocks Offset | |
|
|
Tree Nodes Count | |
|
|
Tree Nodes Offset | |
|
|
Groups Count | |
|
|
Groups Offset | |
|
|
Properties Count | |
|
|
Properties Offset | |
|
|
Padding | Always 0. |
Vertices
Vertices are stored as regular floating point singles.
Size: 0xC bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
X Pos | Floating point X position. |
|
|
Y Pos | Floating point Y position. |
|
|
Z Pos | Floating point Z position. |
Triangles
Triangles are made up of 3 indexes into the vertex section, in addition to indexes for the group they belong to and the property they use.
Size: 0xA bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Vertex 1 Index | |
|
|
Vertex 2 Index | |
|
|
Vertex 3 Index | |
|
|
Property Index | |
|
|
Group Index |
Octree
In order to speed up collision detection, DZB uses an octree to partition parts of the mesh into separate spaces. It is split between two sections: the node tree, and blocks.
Node Tree
The node tree is made up of branch and leaf nodes. Each group in the file that actually has collision assigned to it contains the index of the group's root node.
Nodes have two forms, which are differentiated by the Flags field. Branch nodes have 8 sub-children. There is no required spatial ordering to the children blocks, as best I can tell. The code checks the children in a strange order (2 3 6 7 0 1 4 5), implying this is not just an array of children, but the checks for each of the children are the exact same.
Leaf nodes contain an index into the Blocks section.
Size: 0x14 bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Flags | Low bit is set if a leaf node, otherwise it is a branch node. All other fields are ignored. |
|
|
Parent Node Index | |
|
|
Octant 1 Branch Index | If this is a leaf node, this field instead contains an index into the Blocks section. All other fields after this would be filled with 0xFF. |
|
|
Octant 2 Branch Index | |
|
|
Octant 3 Branch Index | |
|
|
Octant 4 Branch Index | |
|
|
Octant 5 Branch Index | |
|
|
Octant 6 Branch Index | |
|
|
Octant 7 Branch Index | |
|
|
Octant 8 Branch Index |
Blocks
A block defines a series of triangles. The first triangle in the block is specified by the corresponding index, and contains every triangle up until the next block (or the end of the triangles array if there is no next block).
The original game's code categorizes triangles into one of three separate categories: "roof", "wall", and "ground" depending on the normal of the plane, building three separate linked lists for a block, speeding up acceleration even further.
Size: 2 bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Starting Triangle Index |
Groups
Groups form a hierarchy that appears derived from the original structure of the model in Maya. Only the lowest groups in the hierarchy have geometry data attached to them.
In addition to the hierarchy, groups have the ability to transform, scale, and rotate their geometry, though these are rarely used in practice. Confoundingly, groups contain the only indicator of whether geometry is solid, water, or lava.
Size: 0x34 bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Name Offset | |
|
|
X Scale | Floating point X scale. |
|
|
Y Scale | Floating point Y scale. |
|
|
Z Scale | Floating point Z scale. |
|
|
X Rotation | |
|
|
Y Rotation | |
|
|
Z Rotation | |
|
|
Unknown 1 | Usually 0xFFFF, but sometimes 0xDCDC. |
|
|
X Translation | Floating point X translation. |
|
|
Y Translation | Floating point Y translation. |
|
|
Z Translation | Floating point Z translation. |
|
|
Parent Group Index | |
|
|
Next Sibling Group Index | |
|
|
First Child Group Index | |
|
|
Room Index | Index of the room this group belongs to. |
|
|
First Vertex Index | The lowest vertex index that belongs to this group. For groups with no faces, this is 0 instead. This field does not seem to be read or have any effect. |
|
|
Octree Root Node Index | |
|
|
Bitfield | See below |
Bitfield
Mask | Field Name | Description |
---|---|---|
0x000000FF | RTBL Index | The room table index to use when the player is above a triangle in this group. This property allows a single room to load different rooms depending on where the player is physically located in it. For instance, room 0 of the sea uses this to load the correct island room for each sector, and the hub room in DRC uses this to determine if you're in the upper level of the hub or the lower level. |
0x00000100 | Is Water | |
0x00000200 | Is Lava | |
0x00000400 | Unknown 1 | Another attribute bit like Water/Lava, but this one appears unused. Checked in dBgW::ChkGrpThrough. |
0x0007F800 | Sea Floor Audio Info | Officially called "Sound ID", this value is used by the audio system to determine what music to play and what sound banks to load for each sector on the sea. It is 0 for groups that are not part of the sea floor. For groups that are part of the sea floor, bits & 0x3F are the room number this sea floor belongs to. If bit & 0x40 is set, it is the "Inner Sea" part of the sector's sea floor (the center, not near the edge of a sector). If bit & 0x80 is set, it is the "Outer Edge" part of the sector's sea floor (the outermost border of the sector). If neither bit & 0x40 nor bit & 0x80 are set, it is the "Inner Edge" part of the sector's sea floor (the thin border in between the "Inner Sea" and "Outer Edge" parts). Note that collision belonging to room 0 of the sea is slightly different - it is always considered to be part of the sea floor (specifically known as the "Outer Sea"), even if this value is 0. |
0x00080000 | Unknown 2 | Another attribute bit like Water/Lava, but this one appears unused. Checked in dBgW::ChkGrpThrough. |
0xFFF00000 | Unused |
Properties
These give the faces that reference them their attributes, such as whether they trigger an exit, what sound they make when items collide with them, and how Link will interact with them. Most of the data is compressed into 3 bit fields, but there is one int tacked onto the end.
Size: 0x10 bytes.
Offset | Size | Name | Description |
---|---|---|---|
|
|
Bitfield 1 | See below |
|
|
Bitfield 2 | See below |
|
|
Bitfield 3 | See below |
|
|
Bitfield 4 | See below |
Bitfield 1
Mask | Field Name | Description |
---|---|---|
0x000000FF | Cam ID | ? |
0x00001F00 | Sound ID | Sets the sound that plays when Link interacts with the face. |
0x0007E000 | Exit ID | If this is not 0x3F, then the face triggers the exit with this index. Otherwise, the face does nothing. |
0x07F80000 | PolyColor | ? |
0x08000000 | Disable Shadows | Prevents actor shadows from being drawn on this surface. (Only real shadows, does not disable drop shadows.) |
Bitfield 2
Mask | Field Name | Description |
---|---|---|
0x000000FF | LinkNo | ? |
0x00000F00 | Wall Code | Sets the wall type, such as climable like a ladder or grabable like a block. |
0x0000F000 | Special Code | ? |
0x001F0000 | Attribute Code Direct | ? |
0x03E00000 | Ground Code | Sets the terrain type, such as sloped or slippery. |
Bitfield 3
Mask | Field Name | Description |
---|---|---|
0x000000FF | Cam Move BG | ? |
0x0000FF00 | Room Cam ID | ? |
0x00FF0000 | Water Current Room Path Index | Index of a room path that represents a water current's directions. Some objects (specifically the ship, Link when swimming, and crate-type pots) will move along this water current if in water and directly above collision with this field set. |
0xFF000000 | Water Current Room Path Point Index | Index of a point in the above room path. This point represents the direction the water flows from, and the next point represents the direction it flows towards. |
Bitfield 4
Mask | Field Name | Description |
---|---|---|
0x00000001 | Pass 1 Camera | Allows the camera to pass through this surface. |
0x00000002 | Pass 0 Normal | Allows most objects to pass through this surface. |
0x00000004 | Pass 2 Link | Allows Link to pass through this surface. |
0x00000008 | Pass 3 Arrows and Light | Allows arrows and reflected rays of light to pass through this surface. Also prevents actor shadows from being drawn on this surface. (Only real shadows, does not disable drop shadows.) |
0x00000010 | Hookshottable | Allows the hookshot to stick to this surface so the player can pull themself to it. |
0x00000020 | Pass 4 Bombs | Allows bombs to pass through this surface. |
0x00000040 | Pass 5 Boomerang | Allows the boomerang to pass through this surface. |
0x00000080 | Pass 6 Hookshot | Allows the hookshot to pass through this surface.\n(Maybe also allows other things, such as Link's line-of-sight, to pass through...?) |