www.pudn.com > boogiebot.zip > WMORootFile.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace BoogieBot.Common
{
/// WMO Root File. Parses and stores a World Model Object.
public class WMORootFile : WMOFile
{
public MOHD mohd; // WMO Root Header
public List groupNames; // List of Group Names (MOGN chunk)
public MOGI[] groupInfo; // List of Group Info
public MOPV[] portalVertices; // List of Portal Vertices
public MOPT[] portalInfo; // List of Portal Info
public MOPR[] portalGroupRel; // List of Portal <-> Group Relationships
public MODD[] doodadLocations; // List of Doodad Locations in this WMO
public WMORootFile(String filename) : base(filename)
{
}
/*protected override void parseFile(MPQFile mpqfile)
{
MemoryStream ms = mpqfile.GetStream();
BinaryReader bin = new BinaryReader(ms);
BoogieCore.Log(LogType.SystemDebug, "WMORootFile: Parsing {0}... ", mpqfile.Filename);
BlizChunkHeader tempHeader;
long pos = 0;
// Read bytes from the stream until we run out
while (pos < ms.Length)
{
// Advance to the next Chunk
ms.Position = pos;
// Read in Chunk Header Name
tempHeader = new BlizChunkHeader(bin.ReadChars(4), bin.ReadUInt32());
tempHeader.Flip();
// Set pos to the location of the next Chunk
pos = ms.Position + tempHeader.Size;
if (tempHeader.Is("MVER")) // WMO File Version
{
mver = new MVER();
mver.version = bin.ReadUInt32();
continue;
}
if (tempHeader.Is("MOHD")) // WMO Root Header
{
mohd = new MOHD();
mohd.nTextures = bin.ReadUInt32();
mohd.nGroups = bin.ReadUInt32();
mohd.nPortals = bin.ReadUInt32();
mohd.nLights = bin.ReadUInt32();
mohd.nModels = bin.ReadUInt32();
mohd.nDoodads = bin.ReadUInt32();
mohd.nDoodadSets = bin.ReadUInt32();
mohd.ambientColour = bin.ReadUInt32();
mohd.wmoID = bin.ReadUInt32();
mohd.c1 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
mohd.c2 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
mohd.unknown = bin.ReadUInt32();
continue;
}
if (tempHeader.Is("MOTX")) // List of textures (BLP Files) used in this map object.
{
// Not needed.
continue;
}
if (tempHeader.Is("MOMT")) // Materials used in this map object
{
// Not needed.
continue;
}
if (tempHeader.Is("MOGN")) // List of group names for the groups in this map object.
{
byte[] groupNamesChunk = bin.ReadBytes((int)tempHeader.Size);
groupNames = new List();
StringBuilder str = new StringBuilder();
// Convert szString's to a List.
for (int i = 0; i < groupNamesChunk.Length; i++)
{
if (groupNamesChunk[i] == '\0')
{
if (str.Length > 1)
groupNames.Add(str.ToString());
str = new StringBuilder();
}
else
str.Append((char)groupNamesChunk[i]);
}
continue;
}
if (tempHeader.Is("MOGI")) // Group information for WMO groups.
{
uint num = tempHeader.Size / 32;
groupInfo = new MOGI[num];
for (int i = 0; i < num; i++)
{
groupInfo[i].flags = bin.ReadUInt32();
groupInfo[i].c1 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle()); ;
groupInfo[i].c2 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle()); ;
groupInfo[i].nameOffset = bin.ReadInt32();
}
continue;
}
if (tempHeader.Is("MOSB")) // Skybox. If not empty, it contains a model (M2) filename to use as a skybox.
{
// Not needed.
continue;
}
if (tempHeader.Is("MOPV")) // Portal vertices. Portals are (always?) rectangles that specify where doors or entrances are in a WMO.
{
uint num = tempHeader.Size / 48;
portalVertices = new MOPV[num];
for (int i = 0; i < num; i++)
{
portalVertices[i].c1 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
portalVertices[i].c2 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
portalVertices[i].c3 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
portalVertices[i].c4 = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
}
continue;
}
if (tempHeader.Is("MOPT")) // Portal information.
{
uint num = tempHeader.Size / 20;
portalInfo = new MOPT[num];
for (int i = 0; i < num; i++)
{
portalInfo[i].startVertex = bin.ReadUInt16();
portalInfo[i].count = bin.ReadUInt16();
portalInfo[i].w = bin.ReadSingle();
portalInfo[i].x = bin.ReadSingle();
portalInfo[i].y = bin.ReadSingle();
portalInfo[i].z = bin.ReadSingle();
}
continue;
}
if (tempHeader.Is("MOPR")) // Portal - Group relationship
{
uint num = tempHeader.Size / 8;
portalGroupRel = new MOPR[num];
for (int i = 0; i < num; i++)
{
portalGroupRel[i].portalIndex = bin.ReadUInt16();
portalGroupRel[i].groupIndex = bin.ReadUInt16();
portalGroupRel[i].side = bin.ReadInt16();
portalGroupRel[i].filler = bin.ReadUInt16();
}
continue;
}
if (tempHeader.Is("MOVV")) // Visible block vertices.
{
// Do we need this? Don't think so.
continue;
}
if (tempHeader.Is("MOVB")) // Visible block list.
{
// Do we need this? Don't think so.
continue;
}
if (tempHeader.Is("MOLT")) // Lighting information.
{
// Not needed.
continue;
}
if (tempHeader.Is("MODS")) // This chunk defines doodad sets.
{
// Not needed.
continue;
}
if (tempHeader.Is("MODN")) // List of filenames for M2 models that appear in this map tile.
{
// Not needed.
continue;
}
if (tempHeader.Is("MODD")) // Information for doodad instances.
{
uint num = tempHeader.Size / 40;
doodadLocations = new MODD[num];
for (int i = 0; i < num; i++)
{
doodadLocations[i].nameOffset = bin.ReadUInt32();
doodadLocations[i].coord = new Coordinate(bin.ReadSingle(), bin.ReadSingle(), bin.ReadSingle());
doodadLocations[i].q.w = bin.ReadSingle();
doodadLocations[i].q.x = bin.ReadSingle();
doodadLocations[i].q.y = bin.ReadSingle();
doodadLocations[i].q.z = bin.ReadSingle();
doodadLocations[i].scale = bin.ReadSingle();
doodadLocations[i].b = bin.ReadByte();
doodadLocations[i].g = bin.ReadByte();
doodadLocations[i].r = bin.ReadByte();
doodadLocations[i].a = bin.ReadByte();
}
continue;
}
if (tempHeader.Is("MFOG")) // Fog information.
{
// Not Needed.
continue;
}
if (tempHeader.Is("MCVP")) // Convex Volume Planes.
{
// Do we need this? Don't think so.
continue;
}
// If we're still down here, we got a problem
throw new Exception(String.Format("WMORootFile: Woah. Got a header of {0}. Don't know how to deal with this, bailing out.", tempHeader.ToString()));
}
// Further processing after finishing all chunks goes here.
}*/
// MOHD Chunk (WMO Header)
public struct MOHD
{
public UInt32 nTextures;
public UInt32 nGroups;
public UInt32 nPortals;
public UInt32 nLights;
public UInt32 nModels;
public UInt32 nDoodads;
public UInt32 nDoodadSets;
public UInt32 ambientColour;
public UInt32 wmoID;
public Coordinate c1;
public Coordinate c2;
public UInt32 unknown;
}
// MOGI Chunk (Group Info)
public struct MOGI
{
public UInt32 flags;
public Coordinate c1;
public Coordinate c2;
public Int32 nameOffset;
}
// MOPV (Portal Vertices)
public struct MOPV
{
public Coordinate c1;
public Coordinate c2;
public Coordinate c3;
public Coordinate c4;
}
// MOPT Chunk (Portal Info)
public struct MOPT
{
public UInt16 startVertex;
public UInt16 count;
public float w;
public float x;
public float y;
public float z;
}
// MOPR Chunk (Group - Portal Relationship)
public struct MOPR
{
public UInt16 portalIndex;
public UInt16 groupIndex;
public Int16 side;
public UInt16 filler;
}
// MODD Chunk (Doodad Placement)
public struct MODD
{
public UInt32 nameOffset;
public Coordinate coord;
public Quaternion q;
public float scale;
public byte b;
public byte g;
public byte r;
public byte a;
}
// A Quaternion
public struct Quaternion
{
public float w;
public float x;
public float y;
public float z;
}
}
}