예제 #1
0
        public WldDisplay3D(WLD wld,WLD placeables=null,WLD objectMesh=null)
        {
            _wld = wld;
            _placeables = placeables;
            _objects = objectMesh;

            _zoneMeshes = wld.ZoneMeshes;
            BuildPlaceableas();
        }
예제 #2
0
        public void RenderMesh(WLD wld,IEnumerable<Mesh> meshes, TrackAnimationBuilder animation = null, int textureNum = 0, int face = 0)
        {
            if (meshes == null) return;
            Model3DGroup group = Model as Model3DGroup;

            group.Children.Clear();
            Dictionary<BitmapImage, List<EQEmu.Files.WLD.Polygon>> polysbyTex = new Dictionary<BitmapImage, List<EQEmu.Files.WLD.Polygon>>();
            List<EQEmu.Files.WLD.Polygon> untexturedPolys = new List<EQEmu.Files.WLD.Polygon>();
            foreach (var mesh in meshes)
            {
                foreach (var p in mesh.Polygons)
                {
                    if (p.BitmapInfo != null)
                    {
                        if (polysbyTex.ContainsKey(p.BitmapInfo.Image))
                        {
                            polysbyTex[p.BitmapInfo.Image].Add(p);
                        }
                        else
                        {
                            polysbyTex[p.BitmapInfo.Image] = new List<EQEmu.Files.WLD.Polygon>();
                            polysbyTex[p.BitmapInfo.Image].Add(p);
                        }
                    }
                    else
                    {
                        untexturedPolys.Add(p);
                    }
                }
            }

            Material mat = null;
            foreach (var polytex in polysbyTex)
            {
                MeshBuilder builder = new MeshBuilder();
                if (mat == null)
                {
                    if (polytex.Value.ElementAt(0).BitmapInfo != null)
                    {
                        //mat = HelixToolkit.Wpf.MaterialHelper.CreateImageMaterial(polytex.Value.ElementAt(0).Image, 100.0);
                        BitmapImage img = polytex.Value.ElementAt(0).BitmapInfo.Image;
                        if (textureNum > 0 || face > 0)
                        {
                            string baseTexture = polytex.Value.ElementAt(0).BitmapInfo.Name;
                            var textureStr = String.Format("{0:d2}", textureNum);
                            var faceStr = String.Format("{0:d1}", face);

                            var index = baseTexture.IndexOf("00");
                            if (index < 0) index = baseTexture.IndexOf("01");

                            if (index > 0)
                            {
                                var faceAndTexture = baseTexture.Substring(0, index) + textureStr + faceStr + baseTexture.Substring(index + textureStr.Length + faceStr.Length);
                                var textureOnly = baseTexture.Substring(0, index) + textureStr + baseTexture.Substring(index + textureStr.Length);
                                var faceOnly = baseTexture.Substring(0, index + textureStr.Length) + faceStr + baseTexture.Substring(index + textureStr.Length + faceStr.Length);

                                if (wld.ImageMapping.ContainsKey(faceAndTexture))
                                {
                                    img = wld.ImageMapping[faceAndTexture].Image;
                                }
                                else if (wld.ImageMapping.ContainsKey(textureOnly))
                                {
                                    img = wld.ImageMapping[textureOnly].Image;
                                }
                                else if (wld.ImageMapping.ContainsKey(faceOnly))
                                {
                                    img = wld.ImageMapping[faceOnly].Image;
                                }
                            }
                        }

                        var brush = new System.Windows.Media.ImageBrush(img);
                        brush.ViewportUnits = System.Windows.Media.BrushMappingMode.Absolute;
                        //brush.TileMode
                        brush.TileMode = System.Windows.Media.TileMode.Tile;
                        //brush.Stretch = System.Windows.Media.Stretch.Fill;
                        mat = HelixToolkit.Wpf.MaterialHelper.CreateMaterial(brush);
                    }
                    else
                    {
                        mat = Materials.LightGray;
                    }
                }
                foreach (var poly in polytex.Value)
                {
                    Point3D p1 = new Point3D(poly.V1.X, poly.V1.Y, poly.V1.Z);
                    Point3D p2 = new Point3D(poly.V2.X, poly.V2.Y, poly.V2.Z);
                    Point3D p3 = new Point3D(poly.V3.X, poly.V3.Y, poly.V3.Z);

                    if (animation != null)
                    {
                        if (animation.SkeletonPieceTransforms.ContainsKey(poly.V1.BodyPiece))
                        {
                            var atrans = animation.SkeletonPieceTransforms[poly.V1.BodyPiece];
                            p1 = atrans.Transform(p1);
                        }

                        if (animation.SkeletonPieceTransforms.ContainsKey(poly.V2.BodyPiece))
                        {
                            var atrans = animation.SkeletonPieceTransforms[poly.V2.BodyPiece];
                            p2 = atrans.Transform(p2);
                        }

                        if (animation.SkeletonPieceTransforms.ContainsKey(poly.V3.BodyPiece))
                        {
                            var atrans = animation.SkeletonPieceTransforms[poly.V3.BodyPiece];
                            p3 = atrans.Transform(p3);
                        }
                    }

                    var rotate = new RotateTransform3D();
                    rotate.Rotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), 90);
                    p1 = rotate.Transform(p1);
                    p2 = rotate.Transform(p2);
                    p3 = rotate.Transform(p3);

                    if (!Clipping.DrawPoint(p1) || !Clipping.DrawPoint(p2) || !Clipping.DrawPoint(p3))
                    {
                        continue;
                    }

                    //v coordinate - negate it to convert from opengl coordinates to directx
                    var t1 = new System.Windows.Point(poly.V1.U, 1 - poly.V1.V);
                    var t2 = new System.Windows.Point(poly.V2.U, 1 - poly.V2.V);
                    var t3 = new System.Windows.Point(poly.V3.U, 1 - poly.V3.V);

                    //var t1 = new System.Windows.Point(0.0, 0.0);
                    //var t2 = new System.Windows.Point(2.0, 0.0);
                    //var t3 = new System.Windows.Point(0.0, 2.0);
                    //builder.AddTriangle(p3, p2, p1, t3, t2, t1);
                    builder.AddTriangle(p3, p2, p1, t3, t2, t1);
                }
                group.Children.Add(new GeometryModel3D(builder.ToMesh(), mat));
                mat = null;
            }

            //create the untextured polygons... basically a copy and paste from above which sucks... TODO
            var bbuilder = new MeshBuilder();
            mat = Materials.LightGray;
            foreach (var poly in untexturedPolys)
            {
                Point3D p1 = new Point3D(poly.V1.X, poly.V1.Y, poly.V1.Z);
                Point3D p2 = new Point3D(poly.V2.X, poly.V2.Y, poly.V2.Z);
                Point3D p3 = new Point3D(poly.V3.X, poly.V3.Y, poly.V3.Z);
                var rotate = new RotateTransform3D();
                rotate.Rotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), 90);
                p1 = rotate.Transform(p1);
                p2 = rotate.Transform(p2);
                p3 = rotate.Transform(p3);

                if (!Clipping.DrawPoint(p1) || !Clipping.DrawPoint(p2) || !Clipping.DrawPoint(p3))
                {
                    continue;
                }
                bbuilder.AddTriangle(p3, p2, p1);
            }
            group.Children.Add(new GeometryModel3D(bbuilder.ToMesh(), mat));
        }
예제 #3
0
 public void AddWld(WLD wld)
 {
     _wldCollection.Add(wld);
 }
예제 #4
0
        public void RenderModel(WLD modelWld,ModelReference model,int textureNumber=0,int headNumber=0,int face=0)
        {
            var wld = modelWld;
            TrackAnimationBuilder animation = null;
            List<MeshReference> meshrefs = new List<MeshReference>();
            foreach (var refs in model.References)
            {
                var meshref = wld.MeshReferences.Where(x => x.FragmentNumber == refs).FirstOrDefault();
                if (meshref != null)
                {
                    meshrefs.Add(meshref);
                    continue;
                }

                var skel = wld.SkeletonTrackReferences.Where(x => x.FragmentNumber == refs).FirstOrDefault();
                if (skel != null)
                {
                    var skelset = wld.SkeletonTrackSet.Where(x => x.FragmentNumber == skel.SkeletonTrackSetReference).FirstOrDefault();
                    if (skelset != null)
                    {
                        animation = new TrackAnimationBuilder(skelset, wld);

                        foreach (var ms in skelset.MeshReferences)
                        {
                            var m = wld.MeshReferences.Where(x => x.FragmentNumber == ms).FirstOrDefault();
                            if (m != null) meshrefs.Add(m);
                        }
                    }
                }
            }

            List<Mesh> meshes = new List<Mesh>();
            foreach (var m in meshrefs)
            {
                var mesh = wld.ZoneMeshes.FirstOrDefault(x => x.FragmentNumber == m.FragmentReference);
                if (headNumber > 0)
                {
                    //see if it's a head mesh
                    int pos = mesh.FragmentName.IndexOf("HE00");
                    if (pos > 0)
                    {
                        string hNum = String.Format("HE{0:d2}", headNumber);
                        string hMeshName = mesh.FragmentName.Substring(0, pos) + hNum + mesh.FragmentName.Substring(pos + hNum.Length);
                        var hMesh = wld.ZoneMeshes.FirstOrDefault(x => x.FragmentName == hMeshName);
                        if (hMesh != null) mesh = hMesh;
                    }
                }
                if (mesh != null) meshes.Add(mesh);
            }

            if (meshes.Count > 0)
            {
                RenderMesh(wld,meshes, animation, textureNumber,face);
            }
        }
예제 #5
0
        public static WLD Load(Stream stream,string name="default.wld")
        {
            WLD wld = new WLD();
            wld.Name = name;
            int size = Marshal.SizeOf(typeof(WLDHeader));
            var barray = new byte[size];
            stream.Read(barray, 0, size);

            var header = Functions.ByteArrayToStructure<WLDHeader>(barray);

            if (header.Magic != 0x54503d02)
            {
                throw new Exception("Invalid file format");
            }

            if (header.Version == 0x00015500)
            {
                wld._format = Format.Old;
            }
            else if (header.Version == 0x1000C800)
            {
                wld._format = Format.New;
            }
            else
            {
                throw new Exception("Unknown file version");
            }

            //var shash = stream.Position;
            barray = new byte[header.StringHashSize];
            stream.Read(barray, 0, (int)header.StringHashSize);
            wld._sHash = WLD.DecodeFileName(barray);
            wld._strings = wld._sHash.Split('\0');

            var fragCount = header.FragmentCount;

            stream.Seek(size + header.StringHashSize, SeekOrigin.Begin);

            int fragSize = Marshal.SizeOf(typeof(BasicWLDFragment));

            for (int i = 0; i < header.FragmentCount; i++)
            {
                barray = new byte[fragSize];
                stream.Read(barray, 0, fragSize);
                var fragment = Functions.ByteArrayToStructure<BasicWLDFragment>(barray);
                int nameRef = (int)fragment.NameRef;

                var position = stream.Position;

                switch (fragment.Id)
                {
                    case 0x03:
                        var bmpname = new BitmapName(i, nameRef);
                        bmpname.Handler(stream);
                        wld._fragments.Add(bmpname);
                        break;
                    case 0x04:
                        var binfo = new BitmapInfo(i, nameRef);
                        binfo.Handler(stream);
                        wld._fragments.Add(binfo);
                        break;
                    case 0x05:
                        var bitmapInfoRef = new BitmapInfoReference(i, nameRef);
                        bitmapInfoRef.Handler(stream);
                        wld._fragments.Add(bitmapInfoRef);
                        break;
                    case 0x09:
                        break;
                    case 0x10:
                        var skelset = new SkeletonTrackSet(i, nameRef);
                        skelset.Handler(stream);
                        skelset.FragmentName = wld.GetStringAtHashIndex(0-skelset.FragmentNameRef);
                        wld._fragments.Add(skelset);
                        break;
                    case 0x11:
                        var skeltrackRef = new SkeletonTrackReference(i, nameRef);
                        skeltrackRef.Handler(stream);
                        wld._fragments.Add(skeltrackRef);
                        break;
                    case 0x12:
                        var skelpiece = new SkeletonPieceTrack(i, nameRef);
                        skelpiece.Handler(stream);
                        wld._fragments.Add(skelpiece);
                        break;
                    case 0x13:
                        var skelpref = new SkeletonPieceTrackReference(i, nameRef);
                        skelpref.Handler(stream);
                        //skelpref.FragmentName = wld.GetStringAtHashIndex(0 - skelpref.FragmentNameRef);
                        wld._fragments.Add(skelpref);
                        break;
                    case 0x14:
                        var modelref = new ModelReference(i, nameRef);
                        modelref.Handler(stream);
                        modelref.FragmentName = wld.GetStringAtHashIndex(0 - modelref.FragmentNameRef);
                        wld._fragments.Add(modelref);
                        modelref.MagicString = wld.GetStringAtHashIndex(modelref.MagicStringRef);
                        break;
                    case 0x15:
                        var objlocation = new ObjectLocation(i, nameRef);
                        objlocation.Handler(stream);
                        wld._fragments.Add(objlocation);
                        break;
                    case 0x22:
                        //num_0x22++;
                        break;
                    case 0x2d:
                        var meshref = new MeshReference(i, nameRef);
                        meshref.Handler(stream);
                        wld._fragments.Add(meshref);
                        break;
                    case 0x31:
                        var tlist = new TextureList(i, nameRef);
                        tlist.Handler(stream);
                        wld._fragments.Add(tlist);
                        break;
                    case 0x30:
                        var texture = new Texture(i, nameRef);
                        texture.Handler(stream);
                        wld._fragments.Add(texture);
                        break;
                    // Grab the number of vertices and polygons
                    case 0x36:
                        var mesh = new Mesh(i, nameRef);
                        mesh.Handler(stream);
                        wld._fragments.Add(mesh);
                        break;
                }
                stream.Seek(position + fragment.Size - 4, SeekOrigin.Begin);
            }

            return wld;
        }
예제 #6
0
        public void OpenFile(string file,bool getObjects=false,bool useNewTextures=true)
        {
            if (File.Exists(file))
            {
                Task.Factory.StartNew(() =>
                    {
                        S3D s3d = null;
                        int status = 0;

                        status += 5;
                        DoStatusUpdate(status, "Loading " + file);

                        try
                        {
                            s3d = S3D.Load(file);
                        }
                        catch (Exception e)
                        {
                            DoStatusUpdate(0, "Failed loading s3d: " + e.Message, false);
                            return;
                        }

                        _archive = s3d;

                        var filename = System.IO.Path.GetFileName(file);
                        int period = filename.IndexOf('.', 0);
                        var zone = filename.Substring(0, period);
                        string dir = Path.GetDirectoryName(file);

                        //var archiveFile = s3d.Files.FirstOrDefault(x => x.Name.Contains(zone + ".wld"));
                        //if (archiveFile == null) return;

                        _wld = null;
                        _objectLocations = null;
                        List<WLD> wlds = new List<WLD>();

                        foreach (var archive in s3d.Files.Where(x => x.Name.Contains(".wld")))
                        {
                            bool isObjects = archive.Name.Contains("objects.wld");
                            if (isObjects && !getObjects) continue;

                            status += 20;
                            DoStatusUpdate(status, "Loading " + archive.Name);

                            using (var ms = new MemoryStream(archive.Bytes))
                            {
                                WLD wld = null;
                                try
                                {
                                    wld = WLD.Load(ms,archive.Name);
                                    if (useNewTextures) wld.TexturingFormat = WLD.TextureFormat.HighResolution;
                                    else wld.TexturingFormat = WLD.TextureFormat.Original;
                                }
                                catch (Exception e)
                                {
                                    DoStatusUpdate(0, "Failed loading: " + archive.Name + " " + e.Message, false);
                                    return;
                                }
                                wlds.Add(wld);
                                if (archive.Name.Contains(zone + ".wld"))
                                {
                                    _wld = wld;
                                    if (archive.Name.Contains("_obj") || archive.Name.Contains("_chr"))
                                    {
                                        _wld.ResolveMeshNames();
                                    }
                                }
                                else if (isObjects)
                                {
                                    _objectLocations = wld;
                                    if (_objectLocations != null)
                                    {
                                        _objectLocations.ResolveObjectLocationNames();
                                    }
                                }
                            }
                        }
                        _wlds = wlds;

                        //load up the _obj.s3d WLD
                        string objFile = dir + "\\" + zone + "_obj.s3d";

                        if (getObjects && File.Exists(objFile))
                        {
                            status += 10;
                            DoStatusUpdate(status, "Loading " + zone + "_obj.s3d");
                            var objS3d = S3D.Load(objFile);
                            var archive = objS3d.Files.FirstOrDefault(x => x.Name.Contains(".wld"));
                            if (archive != null)
                            {
                                using (var ms = new MemoryStream(archive.Bytes))
                                {
                                    WLD wld = null;
                                    try
                                    {
                                        wld = WLD.Load(ms,archive.Name);
                                    }
                                    catch (Exception e)
                                    {
                                        DoStatusUpdate(0, "Failed loading: " + archive.Name + " " + e.Message, false);
                                        return;
                                    }
                                    wlds.Add(wld);
                                    _objects = wld;
                                    _objects.Files = objS3d;
                                }
                                if (_objects != null)
                                {
                                    _objects.ResolveMeshNames();
                                }
                            }
                        }

                        if (wlds.Count > 0)
                        {
                            status = 90;
                            DoStatusUpdate(status, "Generating Geometry", false);
                            _wld = _wld == null ? wlds.ElementAt(0) : _wld;
                        }

                        _dispatcher.BeginInvoke((Action)(() =>
                        {
                            if (_wld != null)
                            {
                                _wld.Files = s3d;
                                WLDObject = _wld;
                                _wlds = wlds;
                            }

                            Status = new LoadStatus()
                            {
                                PercentDone = 100,
                                OperationDescription = "Done"
                            };
                        }));
                    });
            }
        }