public WldDisplay3D(WLD wld,WLD placeables=null,WLD objectMesh=null) { _wld = wld; _placeables = placeables; _objects = objectMesh; _zoneMeshes = wld.ZoneMeshes; BuildPlaceableas(); }
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)); }
public void AddWld(WLD wld) { _wldCollection.Add(wld); }
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); } }
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; }
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" }; })); }); } }