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 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); } }