DZB

From CloudModding TWW Wiki
Jump to: navigation, search

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.

File Header

The header of the DZB format lays out the offset of each section and the number of entries each of them has.

//0x34/52dec bytes long

/*0x00*/ int NumVertices;
/*0x04*/ int VerticesOffset;

/*0x08*/ int NumFaces;
/*0x0C*/ int FacesOffset;

/*0x10*/ int NumOctreeIndexes;
/*0x14*/ int IndexesOffset;

/*0x18*/ int NumOctreeNodes;
/*0x1C*/ int OctreeOffset;

/*0x20*/ int NumGroups;
/*0x24*/ int GroupsOffset;

/*0x28*/ int NumProperties;
/*0x2C*/ int PropertiesOffset;

/*0x30*/ int Padding;

Vertices

Vertices are stored as regular floating point singles.

//0xC/12dec bytes long

/*0x00*/ float XPos;

/*0x04*/ float YPos;

/*0x08*/ float ZPos;

Faces

Faces 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.

//0xA/10dec bytes long

/*0x00*/ short Vert1Index;

/*0x02*/ short Vert2Index;

/*0x04*/ short Vert3Index;

/*0x06*/ short PropertyIndex;

/*0x08*/ short GroupIndex;

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 actual Tree and octree Indexes.

Tree

The octree 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 leaf. From there, the tree grows until a certain condition is met. That condition is currently unknown.

Nodes have two forms, which are differentiated by a boolean, which will be named IsLeafNode. If it is false, the node is a branch and contains the indexes of other branches or leaves for each octant of the space to be subdivided. If it is true, the node is a leaf and contains the index to an index in the octree Indexes section.

//0x14/20dec bytes long

/*0x00*/ const byte MagicOne = 1;

/*0x01*/ bool IsLeafNode;

/*0x02*/ short ParentNodeIndex;

/*0x04*/ short Octant1BranchIndex; //If IsLeafNode == true, this field instead contains an index into the Octree Indexes section. All other fields after this would be filled with 0xFF.

/*0x06*/ short Octant2BranchIndex;

/*0x08*/ short Octant3BranchIndex;

/*0x0A*/ short Octant4BranchIndex;

/*0x0C*/ short Octant5BranchIndex;

/*0x0E*/ short Octant6BranchIndex;

/*0x10*/ short Octant7BranchIndex;

/*0x12*/ short Octant8BranchIndex;

Indexes

This is the index of a face for the octree to use. By some currently unknown association, this face and others related to it become part of the octant of the leaf that referenced it.

//2 bytes long

/*0x00*/ short FaceIndex;

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.

//0x10/16dec bytes long

/*0x00*/ int Bitfield1; //Contains Cam ID, Exit ID, Sound ID, and PolyColor

/*0x04*/ int Bitfield2; //Contains LinkNo, Wall Code, Special Code, Attribute Code Direct, and Ground Code

/*0x08*/ int Bitfield3; //Contains CamMoveBG, RoomCamID, RoomPathID, and RoomPathPntNo

/*0x0C*/ int CameraBehavior;

Bit field 1

Field Name Purpose Mask
Cam ID  ? 0xFF
Exit ID If this is not 0x1F, then the face triggers the exit with this index. Otherwise, the face does nothing. 0x1F00
Sound ID Sets the sound that plays when Link interacts with the face. 0x7E000
PolyColor  ? 0x7F80000


Bit field 2

Field Name Purpose Mask
LinkNo  ? 0xFF
Wall Code Sets the wall type, such as climable like a ladder or grabable like a block. 0xF00
Special Code  ? 0xF000
Attribute Code Direct  ? 0x1F0000
Ground Code Sets the terrain type, such as sloped or slippery. 0x3E00000

Bit field 3

Field Name Purpose Mask
CamMoveBG  ? 0xFF
RoomCamID  ? 0xFF00
RoomPathID  ? 0xFF0000
RoomPathPntNo  ? 0xFF000000

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.

//0x34/52dec bytes long

/*0x00*/ int NameOffset;
/*0x04*/ float XScale;
/*0x08*/ float YScale;
/*0x0C*/ float ZScale;

/*0x10*/ short XRotation;
/*0x12*/ short YRotation;
/*0x14*/ short ZRotation;
/*0x16*/ short RotPadding;

/*0x18*/ float XTrans;
/*0x1C*/ float YTrans;
/*0x20*/ float ZTrans;

/*0x24*/ short ParentGroupIndex;
/*0x26*/ short NextSiblingGroupIndex;
/*0x28*/ short FirstChildGroupIndex;

/*0x2A*/ short UnknownField1;
/*0x2C*/ short UnknownField2;

/*0x2E*/ short OctreeRootNodeIndex;

/*0x30*/ short UnknownField3;

/*0x32*/ byte TerrainType; //0 = solid ground, 1 = water, 2 = lava

/*0x33*/ byte UnknownField4;