MDB Format
From NWN2Wiki
This Wiki describes the MDB file format for Neverwinter Nights 2 as it is currently understood. It is the primary file format for representing 3d objects in the game.
Contents |
[edit] File Header
All MDB files begin with a header that has a unique signature as well as version information and a list of the available packets. The available packet list hold references what kind of data is in the file and where it is located from the start of the file.
[edit] MDBHeader
A simple header block which has the version of the file and the available packets.
| MDBHeader | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’NWN2’ |
| uint16 | MajorVer | Major version number |
| uint16 | MinorVer | Minor version number |
| uint32 | NumPackets | Number of Packets |
| MDBPacketKey[NumPackets] | Packets | Packet Array |
[edit] MDBPacketKey
The packet key holds the type of packet and the location within the file where that packet begins.
| MDBPacketKey | ||
| Type | Label | Description |
| char[4] | Signature | Packet Signature – RIGD, SKIN, COL2, COL3, HOOK, WALK, COLS, TRRN, HELM, HAIR |
| uint32 | FileOffset | Offset to packet from start of file |
61230637460460621278460
[edit] Packets
Virtually all of the useful information held in the MDB file is contained in packets or blobs of data. The header of the file contains the version and a list of the available packets and where they are in the file. The packets are identified by a 4 character signature and always hold the size of the packet.
[edit] Common
[edit] MDBPacket
Packets always begin with a block indication type of packet it is and how large the packet is. The total size does not include the packet signature and size itself.
| MDBPacket | ||
| Type | Label | Description |
| char[4] | Signature | Packet Signature – RIGD, SKIN, COL2, COL3, HOOK, WALK, COLS, TRRN, HELM, HAIR |
| uint32 | PacketSize | Size of Packet |
[edit] TRI
The Triangle structure is commonly used in the mesh formats and holds the indices of the vertices that define a face on the mesh.
| TRI – Triangle | ||
| Type | Label | Description |
| uint16[3] | Verts | Indices of the vertices that define a triangle face |
[edit] Rigid Body
[edit] RIGD
Rigid bodies are the staple of the MDL format and are the primary format for all static objects. These objects cannot change shape in the game.
Any mesh can be exported as a RIGD object which includes the mesh as well as the materials and texture maps. You are limited to 65535 vertices but really should only have between 1000 - 10000 max for good performance. Note: Due to the way textures and normals are exported, meshes may end up with more vertices than the modelling program indicates.
| RIGD – Rigid Body | ||
| Type | Label | Description |
| char[4] | Signature | Packet signature – always ’RIGD’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| Material | Material | Texture and Material Information |
| uint32 | NumVerts | Number of vertices |
| uint32 | NumFaces | Number of faces |
| RVert[NumVerts] | Verts | Rigid Body Vertices |
| TRI[NumFaces] | Faces | Triangle Faces Indices |
[edit] RVERT – Rigid Body Vertex
The Rigid Body vertex holds all of the information related to a specific vertex in a rigid body mesh including its position the normal tangent and binormal directions and the texture position.
| RVert – Rigid Body Vertex | ||
| Type | Label | Description |
| Point3 | Position | Position |
| Point3 | Normal | Normal |
| Point3 | Tangent | Tangent |
| Point3 | Binormal | Binormal |
| Point3 | UVW | Texture vertex |
[edit] Skinned Body
Skinned bodies are rigid bodies that are rigged so that they can deform when the underlying skeleton is moved.
[edit] SKIN
Skinned objects like those used for creatures are SKIN objects. These are usually bound to a skeleton and this structure holds the weights as well as the vertices for a mesh. The bones for the skeleton which are what are normally animated are not held in the MDB file but in the GR2 file which is a format from the Granny product from RadTools.
| SKIN – Vertex weighted body | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’SKIN’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| char[32] | Skeleton | Skeleton Name |
| Material | Material | Texture and Material Information |
| uint32 | NumVerts | Number of vertices |
| uint32 | NumFaces | Number of faces |
| SVert[NumVerts] | Verts | Skin Vertices |
| TRI[NumFaces] | Faces | Triangle Faces |
[edit] SVERT - Skin Vertex
The Skin vertex structure is similar to the Rigid Body vertex but has additional regarding which bones can deform the mesh and the weight for that bone. The sum of all of the bone weights must be 1.
| SVert – Skin Vertex | ||
| Type | Label | Description |
| Point3 | Position | Position |
| Point3 | Normal | Normal |
| float[4] | BoneWeights | Bone Weights |
| byte[4] | BoneIndices | Bone Indices |
| Point3 | Tangent | Tangent |
| Point3 | Binormal | Binormal |
| Point3 | UVW | Texture vertex |
| float | BoneCount | Max number of bones? |
[edit] Collision Mesh
Skinned bodies are rigid bodies that are rigged so that they can deform when the underlying skeleton is moved.
[edit] COL2
These seem to be less detailed collision meshes. And do not tightly conform to the model. We dont really know the difference between COL2 and COL3 at this time. The naming convention used by Obsidian is to append _C2 to name to COL2 type meshes. This naming convention makes it convenient for tool authors to export these meshes.
Materials do not really seem to be used and is probably there just to make it easier to share code between RIGD, SKIN, COL2, COL3, and WALK packets.
(A possible meaning for COL2 and COL3 may be collision 2D and collision 3D, where 2D collision is flattened to designate walkable areas while 3D collision is used for line of site/scanhit style checks)
| COL2 – Collision Mesh (Type 2) | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’COL2’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| Material | Material | Texture and Material Information |
| uint32 | NumVerts | Number of vertices |
| uint32 | NumFaces | Number of faces |
| CVert[NumVerts] | Verts | Collision Vertices |
| TRI[NumFaces] | Faces | Triangle Faces |
[edit] COL3
These seem to be more detailed collision and conform more closely to the model. We dont really know the difference between COL2 and COL3 at this time. The naming convention used by Obsidian is to append _C2 to name to COL2 type meshes. This naming convention makes it convenient for tool authors to export these meshes.
Materials do not really seem to be used and is probably there just to make it easier to share code between RIGD, SKIN, COL2, COL3, and WALK packets.
| COL3 – Collision Mesh (Type 3) | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’COL3’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| Material | Material | Texture and Material Information |
| uint32 | NumVerts | Number of vertices |
| uint32 | NumFaces | Number of faces |
| CVert[NumVerts] | Verts | Collision Vertices |
| TRI[NumFaces] | Faces | Triangle Faces |
[edit] CVERT
The collision vertex holds the information for position and normals. Again the Normal and UVW do not really seem to be used at this time.
| CVert – Collision Vertex | ||
| Type | Label | Description |
| Point3 | Position | Position |
| Point3 | Normal | Normal |
| Point3 | UVW | Texture vertex |
[edit] COLS
The COLS packet appears to be collision spheres for animated objects. Spheres are one of the best objects to use for collision detection due to the simplicity of the tests involving it. This structure appears to reference bones of the skeleton for skinned meshes.
| COLS – Collision Spheres | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’COLS’ |
| uint32 | PacketSize | Size of Packet |
| uint32 | NumItems | Number of Collision Sphere Items |
| COLSITM[NumItems] | Spheres | Collision Sphere Array |
[edit] COLSITM
The Collision Sphere item appears to be a bone index to sphere radius map but am not completely certain about it at this time.
| COLSITM – Collision Sphere Item | ||
| Type | Label | Description |
| uint32 | Index | Bone Index |
| Float | Radius | Radius |
[edit] Walk Mesh
Walk meshes define where characters may walk and where they cannot. There are parts of the format that are not well understood which probably effect things like material/sounds to be played when walking on meshes.
[edit] WALK
Walk meshes seem to control where you can walk and where you cannot.
Some vertices have unusual values like -1,000,000 to indicate a link to other walk meshes or perhaps non-navigable terrain. In 3d Studio Max, you probably want to use Quad/Tri Patches to create these. The Faces on a Walk mesh have a flag that is unknown and we currently default to 0x21 (33). The naming convension for these meshes is to append _W to the name.
| WALK – Walk Mesh | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’WALK’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| uint32 | uiFlags | Unknown. Always 0. |
| uint32 | NumVerts | Number of vertices |
| uint32 | NumFaces | Number of faces |
| Point3[NumVerts] | Position of the verts | Collision Vertices |
| WTRI[NumFaces] | Faces | Walk Mesh Triangle Faces |
[edit] WTRI
The Walk mesh triangle structure is used in the walk mesh format to holds the indices of the vertices that define a face on the mesh.
| WTRI – Walk mesh triangle face | ||
| Type | Label | Description |
| uint16 | a | Triangle Vertex 1 |
| uint16 | b | Triangle Vertex 2 |
| uint16 | c | Triangle Vertex 3 |
| uint32 | flags | bit flag - see table below for more detail |
The bit flag settings are as follows, please note you should not use more than one material type and refrain from using any of the reserved bits.
| Bit settings for walk triangles | |
| Type | Description< |
| bit 0 | Walkable Bit, 0=non-walkable 1=walkable |
| bit 1-2 | reserved |
| bit 3 | dirt |
| bit 4 | grass |
| bit 5 | stone |
| bit 6 | wood |
| bit 7 | carpet |
| bit 8 | metal |
| bit 9 | swamp |
| bit 10 | mud |
| bit 11 | leaves |
| bit 12 | water |
| bit 13 | puddles |
| bit 14-32 | Reserved |
[edit] Hook Points
Hook points appear to have a number of purposes within the game. Its primary purpose seems to hold the position for doors and indirectly the direction that the door will swing when opened.
[edit] HookPointSize
HookPointSize was found in the .NET assemblies but it’s still in question whether it’s actually used in the MDB format since this enumeration is not used in the .NET code.
enum HookPointSize : uint16
{
StandardDoor,
LargeDoor,
GateDoor
}
[edit] HookPointType
HookPointType was found in the .NET assemblies but it’s still in question whether it’s actually used in the MDB format since this enumeration is not used in the .NET code.
enum HookPointType : uint16
{
Door,
Accessory,
None
}
[edit] HOOK
Hook points are used to attach doors and accessories to a RIGD mesh. For doors, orient the point so that the Z is the hinge axis the door will swing on. Doors swinging inward would rotate from Y to X axis. The naming convension for hook points is that it begins with "hp_" is then is followed by a number starting with 1.
| HOOK – Hook Point | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’HOOK’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| HookPointType | Type? | Hook Point Type (? – always 0) (uint16) |
| HookPointSize | Size? | Hook Point Size (? – always 0) (uint16) |
| Point3 | Position | Position |
| RHMatrix | Orientation | Right-handed Rotation Matrix |
[edit] Hair and Helm Points
Hair and Helm points seem to control how helmets and other items cover or don’t cover hair when equipped.
[edit] MDBHairShorteningBehavior
Flag that controls the shortening behavior of the hair.
enum MDBHairShorteningBehavior : uint32
{
HSB_LOW,
HSB_SHORT,
HSB_PONYTAIL
}
[edit] HAIR
Hair obviously represents hair on a character. It’s not a mesh but rather a point that holds the hair shortening behavior flag. The Position and Orientation does not seem to matter terribly. The naming convention holds that the name contains "XX?_Hair" within the name. The first two characters are creature specific and the question mark is either M or F for male or female hair.
| HAIR – Hair Mesh | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’HAIR’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| MDBHairShorteningBehavior | HairFlag | Hair Flag |
| Point3 | Position | Position |
| RHMatrix | Orientation | Rotation |
[edit] MDBHelmHairHidingBehavior
enum MDBHelmHairHidingBehavior : uint32
{
HHHB_NONE_HIDDEN,
HHHB_HAIR_HIDDEN,
HHHB_PARTIAL_HAIR,
HHHB_HEAD_HIDDEN
}
[edit] HELM
Helm obviously represents helmets on a character. It’s not a mesh but rather a point that holds the hair hiding behavior flag. The Position and Orientation does not seem to matter terribly. The naming convention holds that the name contains "XX?_Helm" within the name. The first two characters are item specific and the question mark is either M or F for male or female hair.
| HELM – Helmet Mesh | ||
| Type | Label | Description |
| char[4] | Signature | File signature – always ’HELM’ |
| uint32 | PacketSize | Size of Packet |
| char[32] | Name | Name |
| MDBHelmHairHidingBehavior | HelmFlag | Helmet Hair Hiding Flag |
| Point3 | Position | Position |
| RHMatrix | Orientation | Rotation |
[edit] Common Data Types
[edit] Point3
This is a fairly standard structure for holding 3-dimensional coordinates. Could be an array or individual x,y,z float values depending your preference.
| Point3 | ||
| Type | Label | Description |
| float[3] | xyz | x/y/z – coordinates |
[edit] Color3
This is a fairly standard structure for holding color information as a float that usually ranges from 0 to 1.
| Color3 | ||
| Type | Label | Description |
| float[3] | Rgb | rgb color information |
[edit] Quat
Quaternions are a fairly compact way to represent rotation of an object and still have good performace. All rotations are assumed to be right-handed.
| Quat – Quaternion | ||
| Type | Label | Description |
| float[4] | Wxyz | WXYZ values for storing rotation information |
[edit] RHMatrix
RHMatrix represents a right-handed rotation matrix. Scale information can also be saved in the matrix but have not encountered that in the game yet.
| RHMatrix | ||
| Type | Label | Description |
| float[3][3] | m | Right Handed Matrix |
[edit] Material
The material data type holds information regarding the texture maps, color and shininess of an object. Most of the major mesh types have a material regardless of whether the mesh will be seen (like in collision meshes.)
| Material | ||
| Type | Label | Description |
| char[32] | DiffuseMap | Diffuse Map |
| char[32] | NormalMap | Normal Map |
| char[32] | TintMap | RGB Tint Map |
| char[32] | GlowMap | Glow Map |
| Point3 | Kd | Diffuse Color |
| Point3 | Ks | Specular Color |
| float | SpecularPower | Specular Power – Shininess/Glossiness |
| float | SpecularValue | Specular Value – Shininess Strength in max |
| uint32 | uiFlags | Texture Flags |
The following is a table of the texture flag bits and their usage. Some usages are speculative and may not be correct.
| Texture Flags | ||
| Flag Name | Flag Code | Notes |
| Alpha_Test | 1 (0x01) | alpha map values from the diffuse map below 50% grey are not drawn |
| Alpha Blend | 2 (0x02) | Should not be used, performance or not implemented ? |
| Additive Blend | 4 (0x04) | Should not be used, performance or not implemented ? |
| Environment Mapping | 8 (0x08) | Creates a mirroring effect on the object |
| Cutscene Mesh | 16 (0x10) | Likely for highest resolution meshes only used in cutscenes |
| Glow | 32 (0x20) | Enables the illumination map to create a glowing effect |
| No_Cast_Shadows | 64 (0x40) | Does not cast shadows |
| Projected Textures | 128 (0x80) | The projected texture flag means that the model will accept UI projected textures such as the spell targeting cursor. Per a DEV post on NWN2 Forum |
