public Mesh GenerateTerrain(MODF.MODFEntry wmoDefinition = null) { if (MOVT == null) { return(null); } var indices = new List <uint>(); for (var i = 0; i < MOVI.Indices.Length; i += 3) { if (((byte)MOPY.Entries[i / 3].Flags & 0x04) != 0 && MOPY.Entries[i / 3].MaterialId != 0xFF) { continue; } indices.AddRange(new uint[] { MOVI.Indices[i], MOVI.Indices[i + 1], MOVI.Indices[i + 2] }); } var mesh = new Mesh { Type = MeshType.Terrain, Indices = indices.ToArray(), Vertices = MOVT.Vertices, Normals = MONR.Normals, }; if (wmoDefinition != null) { return(mesh.Transform(Transformation.GetWMOTransform(wmoDefinition.Position, wmoDefinition.Rotation))); } return(mesh); }
public void AddDungeon(WMORoot model, MODF.MODFEntry def) { var verts = new List <Vector3>(); var inds = new List <Triangle <uint> >(); MapChunk.InsertWMOGeometry(def, model, verts, inds); AddGeometry(verts, inds); }
public static Matrix GetWmoDoodadTransform(MODD.MODDEntry modd, MODF.MODFEntry modf) { var modfTransform = GetTransform(modf.Position, modf.Rotation); var translation = Matrix.Translation(modd.Position); var quatRotation = Matrix.RotationQuaternion(new Quaternion(-modd.Rotation[0], -modd.Rotation[1], -modd.Rotation[2], modd.Rotation[3])); return(Matrix.Scaling(modd.Scale) * quatRotation * translation * modfTransform); }
public static WMOScene GenerateWMOScene(MODF.MODFEntry wmoDefinition, WMORoot model) { return(new WMOScene { Terrain = model.Groups.Select(g => g.GenerateTerrain(wmoDefinition)).OfType <Mesh>() ?? Enumerable.Empty <Mesh>(), Doodads = model.GenerateDoodads(wmoDefinition.DoodadSet, wmoDefinition).OfType <Mesh>() ?? Enumerable.Empty <Mesh>(), Liquids = model.Groups.Select(g => g.GenerateLiquid(wmoDefinition)).OfType <Mesh>() ?? Enumerable.Empty <Mesh>(), }); }
public static Matrix4 GetDoodadTransform(MODD.MODDEntry modd, MODF.MODFEntry modf) { var placementMatrix = Matrix4.Identity; placementMatrix = Matrix4.Mult(GetWMOTransform(modf.Position, modf.Rotation), placementMatrix); placementMatrix = Matrix4.Mult(Matrix4.CreateTranslation(modd.Position), placementMatrix); placementMatrix = Matrix4.Mult(Matrix4.CreateFromQuaternion(modd.Rotation), placementMatrix); placementMatrix = Matrix4.Mult(Matrix4.CreateScale(modd.Scale), placementMatrix); return(placementMatrix); }
public IEnumerable <Mesh> GenerateDoodads(ushort doodadSet, MODF.MODFEntry wmoDefinition = null) { var set = MODS.Entries[doodadSet]; for (var i = set.FirstInstanceIndex; i < (set.nDoodads + set.FirstInstanceIndex); i++) { if (i >= MODD.Entries.Length) { break; } yield return(GenerateDoodad(MODD.Entries[(int)i], wmoDefinition)); } }
public Mesh GenerateLiquid(MODF.MODFEntry wmoDefinition = null) { if (MLIQ == null) { return(null); } var vertices = new List <Vector3>((int)(MLIQ.Height * MLIQ.Width) * 4); var indices = new List <uint>((int)((MLIQ.Height * MLIQ.Width) * 3)); var relPos = MLIQ.Position; for (var y = 0; y < MLIQ.Height; y++) { for (var x = 0; x < MLIQ.Width; x++) { if (!MLIQ.ShouldRender(x, y)) { continue; } var vo = (uint)vertices.Count; vertices.AddRange(new[] { relPos - new Vector3(x * Constants.UnitSize, y * Constants.UnitSize, MLIQ.HeightMap[x, y]), relPos - new Vector3((x + 1) * Constants.UnitSize, y * Constants.UnitSize, MLIQ.HeightMap[x + 1, y]), relPos - new Vector3(x * Constants.UnitSize, (y + 1) * Constants.UnitSize, MLIQ.HeightMap[x, y + 1]), relPos - new Vector3((x + 1) * Constants.UnitSize, (y + 1) * Constants.UnitSize, MLIQ.HeightMap[x + 1, y + 1]) }); indices.AddRange(new uint[] { vo, vo + 2, vo + 1, vo + 2, vo + 3, vo + 1 }); } } var mesh = new Mesh { Type = MeshType.Liquid, Indices = indices.ToArray(), Vertices = vertices.ToArray(), }; if (wmoDefinition != null) { return(mesh.Transform(Transformation.GetWMOTransform(wmoDefinition.Position, wmoDefinition.Rotation))); } return(mesh); }
public Mesh GenerateDoodad(MODD.MODDEntry doodadDefinition, MODF.MODFEntry wmoDefinition = null) { string path; if (!MODN.Filenames.TryGetValue(doodadDefinition.ofsMODN, out path)) { return(null); } var doodad = new M2(path); if (!doodad.IsCollidable) { return(null); } if (wmoDefinition != null) { return(doodad.Mesh.Transform(Transformation.GetDoodadTransform(doodadDefinition, wmoDefinition))); } return(doodad.Mesh); }
public static void InsertWMOGeometry(MODF.MODFEntry wmo, WMORoot model, List <Vector3> vertices, List <Triangle <uint> > indices) { var transform = Transformation.GetTransform(wmo.Position, wmo.Rotation); foreach (var group in model.Groups) { var vo = (uint)vertices.Count; foreach (var v in group.MOVT.Vertices) { vertices.Add((Vector3)Vector3.Transform(v, transform)); } for (int i = 0; i < group.MOVI.Indices.Length; i++) { if (((byte)group.MOPY.Entries[i].Flags & 0x04) != 0 && group.MOPY.Entries[i].MaterialId != 0xFF) { continue; } var idx = group.MOVI.Indices[i]; indices.Add(new Triangle <uint>(TriangleType.Wmo, vo + idx.V0, vo + idx.V1, vo + idx.V2)); } } if (wmo.DoodadSet >= 0 && wmo.DoodadSet < model.MODS.Entries.Length) { var set = model.MODS.Entries[wmo.DoodadSet]; var instances = new List <MODD.MODDEntry>((int)set.nDoodads); for (uint i = set.FirstInstanceIndex; i < (set.nDoodads + set.FirstInstanceIndex); i++) { if (i >= model.MODD.Entries.Length) { break; } instances.Add(model.MODD.Entries[(int)i]); } foreach (var instance in instances) { string path; if (!model.MODN.Filenames.TryGetValue(instance.ofsMODN, out path)) { continue; } var doodad = new M2(path); if (!doodad.IsCollidable) { continue; } var doodadTransform = Transformation.GetWmoDoodadTransform(instance, wmo); var vo = (uint)vertices.Count; foreach (var v in doodad.Vertices) { vertices.Add((Vector3)Vector3.Transform(v, doodadTransform)); } foreach (var t in doodad.Indices) { indices.Add(new Triangle <uint>(TriangleType.Doodad, t.V0 + vo, t.V1 + vo, t.V2 + vo)); } } } foreach (var group in model.Groups) { if ((group.LiquidVertices == null || group.LiquidVertices.Count == 0) || (group.LiquidIndices == null || group.LiquidIndices.Count == 0)) { continue; } var vo = (uint)vertices.Count; foreach (var v in group.LiquidVertices) { vertices.Add((Vector3)Vector3.Transform(v, transform)); } foreach (var t in group.LiquidIndices) { indices.Add(new Triangle <uint>(t.Type, t.V1 + vo, t.V0 + vo, t.V2 + vo)); } } }