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);
        }
Example #3
0
        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);
                    }
                }
        }
Example #4
0
        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);
                    }
                }
            }
        }