private List <Converter.XmlEdge> createXmlEdges(List <Geometry.Segment2D> graphSegments, List <Converter.XmlVertex> xmlVertices) { List <Converter.XmlEdge> xmlEdges = new List <XmlEdge>(); foreach (Segment2D currentSegment in graphSegments) { Vector2D segmentsStart = currentSegment.getVertices()[0]; Vector2D segmentsEnd = currentSegment.getVertices()[1]; XmlVertex edgesLeftVertex = this.getEqualXmlVertex(xmlVertices, segmentsStart); XmlVertex edgesRightVertex = this.getEqualXmlVertex(xmlVertices, segmentsEnd); xmlEdges.Add(xmlFactory.createXmlEdge(edgesLeftVertex.getId(), edgesRightVertex.getId())); } return(xmlEdges); }
private Converter.XmlVertex getEqualXmlVertex(List <Converter.XmlVertex> vertices, Vector2D segmentPoint) { XmlVertex equalVertex = null; foreach (XmlVertex currentVertex in vertices) { if (currentVertex.getCenter().isEqualTo(segmentPoint, decimalPlaces)) { equalVertex = currentVertex; break; } else { continue; } } return(equalVertex); }
public static IEnumerable <GeometryMesh> GetMeshes(ICacheFile cache, ResourceIdentifier resourcePointer, IEnumerable <SectionBlock> sections, Action <SectionBlock, GeometryMesh> setProps, Func <int, int, int> mapNode = null) { VertexBufferInfo[] vertexBufferInfo; IndexBufferInfo[] indexBufferInfo; var resourceGestalt = cache.TagIndex.GetGlobalTag("zone").ReadMetadata <cache_file_resource_gestalt>(); var entry = resourceGestalt.ResourceEntries[resourcePointer.ResourceIndex]; using (var cacheReader = cache.CreateReader(cache.DefaultAddressTranslator)) using (var reader = cacheReader.CreateVirtualReader(resourceGestalt.FixupDataPointer.Address)) { reader.Seek(entry.FixupOffset + (entry.FixupSize - 24), SeekOrigin.Begin); var vertexBufferCount = reader.ReadInt32(); reader.Seek(8, SeekOrigin.Current); var indexBufferCount = reader.ReadInt32(); reader.Seek(entry.FixupOffset, SeekOrigin.Begin); vertexBufferInfo = reader.ReadEnumerable <VertexBufferInfo>(vertexBufferCount).ToArray(); reader.Seek(12 * vertexBufferCount, SeekOrigin.Current); //12 byte struct here for each vertex buffer indexBufferInfo = reader.ReadEnumerable <IndexBufferInfo>(indexBufferCount).ToArray(); //12 byte struct here for each index buffer //4x 12 byte structs here } using (var ms = new MemoryStream(resourcePointer.ReadData(PageType.Auto))) using (var reader = new EndianReader(ms, cache.ByteOrder)) { var doc = new XmlDocument(); doc.LoadXml(cache.Metadata.IsMcc ? Resources.MccHalo3VertexBuffer : Resources.Halo3VertexBuffer); var lookup = doc.DocumentElement.ChildNodes.Cast <XmlNode>() .ToDictionary(n => Convert.ToInt32(n.Attributes[XmlVertexField.Type].Value, 16)); var sectionIndex = -1; foreach (var section in sections) { sectionIndex++; if (section.VertexBufferIndex < 0 || section.IndexBufferIndex < 0) { yield return(new GeometryMesh()); continue; } var node = lookup[section.VertexFormat]; var vInfo = vertexBufferInfo[section.VertexBufferIndex]; var iInfo = indexBufferInfo[section.IndexBufferIndex]; Func <XmlNode, string, bool> hasUsage = (n, u) => { return(n.ChildNodes.Cast <XmlNode>().Any(c => c.Attributes?[XmlVertexField.Usage]?.Value == u)); }; var skinType = VertexWeights.None; if (hasUsage(node, XmlVertexUsage.BlendIndices)) { skinType = hasUsage(node, XmlVertexUsage.BlendWeight) ? VertexWeights.Skinned : VertexWeights.Rigid; } else if (section.NodeIndex < byte.MaxValue) { skinType = VertexWeights.Rigid; } var mesh = new GeometryMesh { IndexFormat = iInfo.IndexFormat, Vertices = new IVertex[vInfo.VertexCount], VertexWeights = skinType, NodeIndex = section.NodeIndex == byte.MaxValue ? (byte?)null : section.NodeIndex }; setProps(section, mesh); mesh.Submeshes.AddRange( section.Submeshes.Select(s => new GeometrySubmesh { MaterialIndex = s.ShaderIndex, IndexStart = s.IndexStart, IndexLength = s.IndexLength }) ); var address = entry.ResourceFixups[section.VertexBufferIndex].Offset & 0x0FFFFFFF; reader.Seek(address, SeekOrigin.Begin); for (int i = 0; i < vInfo.VertexCount; i++) { var vert = new XmlVertex(reader, node); mesh.Vertices[i] = vert; } if (mapNode != null && (skinType == VertexWeights.Skinned || skinType == VertexWeights.Rigid)) { foreach (var v in mesh.Vertices) { foreach (var bi in v.BlendIndices) { bi.X = mapNode(sectionIndex, (int)bi.X); bi.Y = mapNode(sectionIndex, (int)bi.Y); bi.Z = mapNode(sectionIndex, (int)bi.Z); bi.W = mapNode(sectionIndex, (int)bi.W); } } } var totalIndices = section.Submeshes.Sum(s => s.IndexLength); address = entry.ResourceFixups[vertexBufferInfo.Length * 2 + section.IndexBufferIndex].Offset & 0x0FFFFFFF; reader.Seek(address, SeekOrigin.Begin); if (vInfo.VertexCount > ushort.MaxValue) { mesh.Indicies = reader.ReadEnumerable <int>(totalIndices).ToArray(); } else { mesh.Indicies = reader.ReadEnumerable <ushort>(totalIndices).Select(i => (int)i).ToArray(); } yield return(mesh); } } }
public static IEnumerable <GeometryMesh> GetMeshes(Module module, ModuleItem item, IList <SectionBlock> sections, int lod, Func <SectionBlock, short?> boundsIndex, Func <int, int, int> mapNode = null) { VertexBufferInfo[] vertexBufferInfo; IndexBufferInfo[] indexBufferInfo; var resourceIndex = module.Resources[item.ResourceIndex]; var resource = module.Items[resourceIndex]; //this will be the [mesh resource!*] tag if (resource.ResourceCount > 0) { System.Diagnostics.Debugger.Break(); } using (var blockReader = resource.CreateReader()) { var header = new MetadataHeader(blockReader); using (var reader = blockReader.CreateVirtualReader(header.GetSectionOffset(1))) { //DataBlock 0: mostly padding, buffer counts //DataBlock 1: vertex buffer infos //DataBlock 2: index buffer infos //DataBlock 3+: additional vertex data block for each buffer //DataBlock n+: additional index data block for each buffer var block = header.DataBlocks[0]; reader.Seek(block.Offset + 16, SeekOrigin.Begin); var vertexBufferCount = reader.ReadInt32(); reader.Seek(block.Offset + 44, SeekOrigin.Begin); var indexBufferCount = reader.ReadInt32(); block = header.DataBlocks[1]; reader.Seek(block.Offset, SeekOrigin.Begin); vertexBufferInfo = reader.ReadEnumerable <VertexBufferInfo>(vertexBufferCount).ToArray(); block = header.DataBlocks[2]; reader.Seek(block.Offset, SeekOrigin.Begin); indexBufferInfo = reader.ReadEnumerable <IndexBufferInfo>(indexBufferCount).ToArray(); } using (var reader = blockReader.CreateVirtualReader(header.GetSectionOffset(2))) { var doc = new XmlDocument(); doc.LoadXml(Resources.Halo5VertexBuffer); var lookup = doc.DocumentElement.ChildNodes.Cast <XmlNode>() .ToDictionary(n => Convert.ToInt32(n.Attributes[XmlVertexField.Type].Value, 16)); var sectionIndex = -1; foreach (var section in sections) { sectionIndex++; var lodData = section.SectionLods[Math.Min(lod, section.SectionLods.Count - 1)]; if (lodData.VertexBufferIndex < 0 || lodData.IndexBufferIndex < 0 || !lookup.ContainsKey(section.VertexFormat)) { yield return(new GeometryMesh()); continue; } var node = lookup[section.VertexFormat]; var vInfo = vertexBufferInfo[lodData.VertexBufferIndex]; var iInfo = indexBufferInfo[lodData.IndexBufferIndex]; var mesh = new GeometryMesh { IndexFormat = section.IndexFormat, Vertices = new IVertex[vInfo.VertexCount], VertexWeights = VertexWeights.None, NodeIndex = section.NodeIndex == byte.MaxValue ? (byte?)null : section.NodeIndex, BoundsIndex = 0 }; try { mesh.Submeshes.AddRange( lodData.Submeshes.Select(s => new GeometrySubmesh { MaterialIndex = s.ShaderIndex, IndexStart = s.IndexStart, IndexLength = s.IndexLength }) ); var block = header.DataBlocks[3 + lodData.VertexBufferIndex]; reader.Seek(block.Offset, SeekOrigin.Begin); for (int i = 0; i < vInfo.VertexCount; i++) { var vert = new XmlVertex(reader, node); mesh.Vertices[i] = vert; } block = header.DataBlocks[3 + vertexBufferInfo.Length + lodData.IndexBufferIndex]; reader.Seek(block.Offset, SeekOrigin.Begin); if (vInfo.VertexCount > ushort.MaxValue) { mesh.Indicies = reader.ReadEnumerable <int>(iInfo.IndexCount).ToArray(); } else { mesh.Indicies = reader.ReadEnumerable <ushort>(iInfo.IndexCount).Select(i => (int)i).ToArray(); } } catch { System.Diagnostics.Debugger.Break(); } yield return(mesh); } } } }