WMO

From wowdev
Jump to navigation Jump to search

WMO Files

WMO files contain world map objects. They, too, have a chunked structure just like the WDT files.

There are two types of WMO files, actually:

   * #WMO root file - lists textures (BLP Files), doodads (M2 or MDX Files), etc., and orientation for the WMO groups
   * #WMO group file - 3d model data for one unit in the world map object 

The root file and the groups are stored with the following filenames:

World\wmo\path\WMOName.wmo World\wmo\path\WMOName_NNN.wmo [edit]

WMO root file

The root file lists the following:

   * textures (BLP File references)
   * materials
   * models (M2 File references)
   * groups
   * visibility information
   * more data


MOHD chunk

Header for the map object. 64 bytes.

Offset 	Type 	Description
0x00 	uint32 	nTextures - number of textures (BLP Files)
0x04 	uint32 	nGroups - number of WMO groups
0x08 	uint32 	nPortals - number of portals
0x0C 	uint32 	nLights - number of lights
0x10 	uint32 	nModels - number of M2 models imported
0x14 	uint32 	nDoodads - number of doodads (M2 instances)
0x18 	uint32 	nSets - number of doodad sets
0x1C 	uint32 	ambient color?
0x20 	uint32 	WMO ID (column 2 in WMOAreaTable.dbc)
0x24 	float[3] 	Bounding box corner 1
0x30 	float[3] 	Bounding box corner 2
0x3C 	uint32 	always 0?
struct SMOHeader // 03-29-2005 By ObscuR
{
/*000h*/  UINT32 nTextures;		
/*004h*/  UINT32 nGroups;		
/*008h*/  UINT32 nPortals;		
/*00Ch*/  UINT32 nLights;		
/*010h*/  UINT32 nDoodadNames;		
/*014h*/  UINT32 nDoodadDefs;		
/*018h*/  UINT32 nDoodadSets;		
/*01Ch*/  float ambColor[6];		
/*020h*/ 
/*024h*/  	
/*028h*/  		
/*02Ch*/ 	
/*030h*/  float pos[2];		
/*034h*/  		
/*038h*/  		
/*03Ch*/   UINT32 wmoID;		
/*040h*/ 
};


MOTX chunk

List of textures (BLP Files) used in this map object. A block of zero-padded, zero-terminated strings, that are complete filenames with paths. There will be further material information for each texture in the next chunk. The gaps between the filenames are padded with extra zeroes, but the material chunk does have some positional information for these strings.

There are nTextures entries in this chunk.


MOMT chunk

Materials used in this map object, 64 bytes per texture (BLP file), nTextures entries.

Only the known fields are documented here.

Offset 	Type 	Description
0x00 	uint32 	Flags (?)
0x08 	uint32 	Blending: 0 for opaque, 1 for transparent
0x0C 	uint32 	Start position for the texture filename in the MOTX data block
0x18 	uint32 	End position for the texture filename in the MOTX data block
0x1C 	4 * uint8 	Looks like an RGBA color?
struct SMOMaterial // 03-29-2005 By ObscuR
{
/*000h*/  UINT32 version;		
/*004h*/  UINT32 flags;		
/*008h*/  UINT32 blendMode;		
/*00Ch*/  UINT32 diffuseNameIndex;		
/*010h*/  float sidnColor[3];		
/*014h*/  		
/*018h*/ 		
/*01Ch*/  UINT32 frameSidnColor[3];		
/*020h*/  	
/*024h*/   	
/*028h*/  UINT32 envNameIndex;
/*02Ch*/  float diffColor[3] 		
/*030h*/   		
/*034h*/  		
/*038h*/  UINT32 groundType;		
/*03Ch*/  UINT32 hMaps;		
/*040h*/ 		
}

The field that looks like a color value is green for some of the wooden textures in human buildings, so it is obviously not a texture color. So its purpose is unknown.

The flags might used to tweak alpha testing values, I'm not sure about it, but some grates and flags in IF seem to require an alpha testing threshold of 0, at other places this is greater than 0.

Flag 	Meaning
0x01 	 ?
0x04 	Two-sided (disable backface culling)
0x10 	Bright at night (unshaded) (used on windows and lamps in Stormwind, for example) -ProFeT: i think that is Unshaded becase external face of windows are flagged like this.
0x20 	 ?
0x28 	Darkned ?, the intern face of windows are flagged 0x28
0x40 	 ?
0x80 	 ?


MOGN chunk

List of group names for the groups in this map object. A contiguous block of zero-terminated strings. The names are purely informational, they aren't used elsewhere (to my knowledge)

There are nGroups entries in this chunk.


MOGI chunk

Group information for WMO groups, 32 bytes per group, nGroups entries.

Offset 	Type 	Description
0x00 	uint32 	Flags
0x04 	3 * float 	Bounding box corner 1
0x10 	3 * float 	Bounding box corner 2
0x1C 	int32 	name offset in MOGN chunk (or -1 for no name?)

Groups don't have placement or orientation information, because the coordinates for the vertices in the additional .WMO files are already correctly transformed relative to (0,0,0) which is the entire WMO's base position in model space.

The name offsets seem to be incorrect (or something else entirely?). The correct name offsets are in the WMO group file headers. (along with more descriptive names for some groups)

The flags for the groups seem to specify whether it is indoors/outdoors, probably to choose what kind of lighting to use. Not fully understood. "Indoors" and "Outdoors" are flags used to tell the client whether certain spells can be cast and abilities used. (Example: Entangling Roots cannot be used indoors).

Flag 	Meaning
0x8 	Outdoor (use global lights?)
0x40 	 ?
0x80 	 ?
0x2000 	Indoor (use local lights?)
0x8000 	Unknown, but frequently used
0x10000 	Used in Stormwind?
0x40000 	Show skybox if the player is "inside" the group


MOSB chunk

Skybox. If not empty, it contains a model (M2) filename to use as a skybox. Used in: Caverns of Time, Stratholme, Dire Maul, Death (Ghost World).

The regular "stars" skybox as seen outdoors at night is hardcoded into WoW.exe.

Skyboxes are also used in-game when you die (and have the swirling green clouds around you). There is also a skybox model used in Dire Maul, which is not shaped the same way as the Stratholme and Caverns of Time skyboxes.


MOPV chunk

Portal vertices, 4 * 3 * float per portal, nPortals entries.

Portals are (always?) rectangles that specify where doors or entrances are in a WMO. They could be used for visibility, but I currently have no idea what relations they have to each other or how they work.

this part removed because there are proper holes in the terrain

Since when "playing" WoW, you're confined to the ground, checking for passing through these portals would be enough to toggle visibility for indoors or outdoors areas, however, when randomly flying around, this is not necessarily the case.


So.... What happens when you're flying around on a gryphon, and you fly into that arch-shaped portal into Ironforge? How is that portal calculated?

   * It's all cool as long as you're inside "legal" areas, I suppose. 

It's fun, you can actually map out the topology of the WMO using this and the MOPR chunk. This could be used to speed up the rendering once/if I figure out how. Here are some example topologies: Deeprun Tram Orgrimmar Stormwind Ironforge


MOPT chunk

Portal information. 20 bytes per portal, nPortals entries. Offset Type Description

0x00 	uint16 	Base vertex index?
0x02 	uint16 	Number of vertices (?), always 4 (?)
0x04 	3 * float 	a normal vector maybe? haven't checked.
0x10 	float 	unknown
struct SMOPortal  // 04-29-2005 By ObscuR
{
/*000h*/  UINT16 startVertex;
/*002h*/  UINT16 count;
/*004h*/  float  plane[4];
/*014h*/  
};


MOPR chunk

Portal - group relationship? 2*nPortals entries of 8 bytes. I think this might specify the two WMO groups that a portal connects.

Offset 	Type 	Description
0x0 	uint16 	Portal index
0x2 	uint16 	WMO group index
0x4 	int16 	1 or -1
0x6 	uint16 	always 0
struct SMOPortalRef // 04-29-2005 By ObscuR
{
/*000h*/  UINT16 portalIndex;
/*000h*/  UINT16 groupIndex;
/*004h*/  UINT16 side;
/*006h*/  UINT16 filler;
/*008h*/
};


MOVV chunk

Visible block vertices

Just a list of vertices that corresponds to the visible block list.


MOVB chunk

Visible block list

unsigned short firstVertex; unsigned short count;


MOLT chunk

Lighting information. 48 bytes per light, nLights entries

Offset 	Type 	Description
0x00 	4 * uint8 	Flags or something? Mostly (0,1,1,1)
0x04 	4 * uint8 	Color (B,G,R,A)
0x08 	3 * float 	Position (X,Z,-Y)
0x14 	7 * float 	Unknown (light properties?)
enum LightType 
{
	OMNI_LGT,
	SPOT_LGT,
	DIRECT_LGT,
	AMBIENT_LGT
};

struct SMOLight // 04-29-2005 By ObscuR
{
/*000h*/  UINT8 LightType; 	
/*001h*/  UINT8 type;
/*002h*/  UINT8 useAtten;
/*003h*/  UINT8 pad;
/*004h*/  UINT8 color[4];  
/*008h*/  float position[3];
/*014h*/  float intensity;
/*018h*/  float attenStart;
/*01Ch*/  float attenEnd;
/*020h*/  float unk1;
/*024h*/  float unk2;
/*028h*/  float unk3;
/*02Ch*/  float unk4;
/*030h*/  
};

I haven't quite figured out how WoW actually does lighting, as it seems much smoother than the regular vertex lighting in my screenshots. The light paramters might be range or attenuation information, or something else entirely. Some WMO groups reference a lot of lights at once.

The WoW client (at least on my system) uses only one light, which is always directional. Attenuation is always (0, 0.7, 0.03). So I suppose for models/doodads (both are M2 files anyway) it selects an appropriate light to turn on. Global light is handled similarly. Some WMO textures (BLP files) have specular maps in the alpha channel, the pixel shader renderpath uses these. Still don't know how to determine direction/color for either the outdoor light or WMO local lights... :)


MODS chunk

This chunk defines doodad sets. Doodads in WoW are M2 model files. There are 32 bytes per doodad set, and nSets entries. Doodad sets specify several versions of "interior decoration" for a WMO. Like, a small house might have tables and a bed laid out neatly in one set called "Set_$DefaultGlobal", and have a horrible mess of abandoned broken things in another set called "Set_Abandoned01". The names are only informative.

Offset 	Type 	Description
0x00 	20 * char 	Set name
0x14 	uint32 	index of first doodad instance in this set
0x18 	uint32 	number of doodad instances in this set
0x1C 	uint32 	unused? (always 0)

The doodad set number for every WMO instance is specified in the ADT files.


MODN chunk

List of filenames for M2 models that appear in this map tile. A block of zero-padded, zero-terminated strings. There are nModels file names in this list.


MODD chunk

Information for doodad instances. While WMOs and models (M2s) in a map tile are rotated along the axes, doodads within a WMO are oriented using quaternions! Hooray for consistency!

40 bytes per doodad instance, nDoodads entries.

Offset 	Type 	Description
0x00 	uint32 	Offset to the start of the model's filename in the MODN chunk.
0x04 	3 * float 	Position (X,Z,-Y)
0x10 	float 	W component of the orientation quaternion
0x14 	3 * float 	X, Y, Z components of the orientaton quaternion
0x20 	float 	Scale factor
0x24 	4 * uint8 	(B,G,R,A) color. Unknown. It is often (0,0,0,255). (something to do with lighting maybe?)
struct SMODoodadDef // 03-29-2005 By ObscuR
{
/*000h*/  UINT32 nameIndex
/*004h*/  float pos[3];
/*010h*/  float rot[4];
/*020h*/  float scale;
/*024h*/  UINT8 color[4];
/*028h*/
};

I had to do some tinkering and mirroring to orient the doodads correctly using the quaternion, see model.cpp in the WoWmapview source code for the exact transform matrix. It's probably because I'm using another coordinate system, as a lot of other coordinates in WMOs and models also have to be read as (X,Z,-Y) to work in my system. But then again, the ADT files have the "correct" order of coordinates. Weird.


MFOG chunk

Fog information. Made up of blocks of 48 bytes.

struct SMOFog // 03-29-2005 By ObscuR
{
/*000h*/  UINT32 flags;		
/*004h*/  float pos[3];		
/*008h*/ 	
/*00Ch*/  		
/*010h*/  float start[3];		
/*014h*/  		
/*018h*/ 		
/*01Ch*/  float end[3];			
/*020h*/  	
/*024h*/   	
/*028h*/  float fogs[2];
/*02Ch*/  	
/*030h*/		
}

For enUS 1.2.x (and above), seems to be different from the preceding struct:

Offset 	Type 	Description
0x00 	uint32 	Flags
0x04 	float[3] 	Position
0x10 	float 	Smaller radius
0x14 	float 	Larger radius
0x18 	float 	Fog end
0x1C 	float 	Fog start multiplier (0..1)
0x20 	uint32 	Fog color
0x24 	float 	Unknown (almost always 222.222)
0x28 	float 	Unknown (-1 or -0.5)
0x2C 	uint32 	Color 2

Fog end: This is the distance at which all visibility ceases, and you see no objects or terrain except for the fog color.

Fog start: This is where the fog starts. Obtained by multiplying the fog end value by the fog start multiplier.


MCVP chunk

Convex Volume Planes. Contains blocks of floating-point numbers.

WMO group file