Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
 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>(),
     });
 }
Пример #5
0
        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);
        }
Пример #6
0
        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));
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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));
                }
            }
        }