예제 #1
0
 /// <summary>
 ///     Initialize with no data.
 /// </summary>
 public G1Model()
 {
     Section = new ResourceSectionHeader
     {
         Magic   = DataType.Model,
         Size    = -1,
         Version = SupportedVersion.ToVersionA()
     };
     SectionRoot = new PackedResource();
 }
예제 #2
0
        /// <summary>
        ///     Parse G1M from the provided data buffer
        /// </summary>
        /// <param name="data"></param>
        /// <param name="ignoreVersion"></param>
        /// <param name="parse"></param>
        public G1Model(Span <byte> data, bool ignoreVersion = true, bool parse = true)
        {
            if (!data.Matches(DataType.Model))
            {
                throw new InvalidOperationException("Not an G1M stream");
            }

            Section = MemoryMarshal.Read <ResourceSectionHeader>(data);
            if (!ignoreVersion && Section.Version.ToVersion() != SupportedVersion)
            {
                throw new NotSupportedException($"G1M version {Section.Version.ToVersion()} is not supported!");
            }

            var header = MemoryMarshal.Read <ModelHeader>(data.Slice(0xC));

            SectionRoot = new PackedResource(data.Slice(header.HeaderSize, Section.Size - header.HeaderSize), header.SectionCount);
            // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
            foreach (var block in SectionRoot.Sections)
            {
                var sectionHeader = MemoryMarshal.Read <ResourceSectionHeader>(block.Span);
                var dataBlock     = block.Span.Slice(SizeHelper.SizeOf <ResourceSectionHeader>());
                if (!parse)
                {
                    Sections.Add(new G1MStub(dataBlock, sectionHeader));
                    continue;
                }

                // ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
                var section = sectionHeader.Magic switch
                {
                    DataType.G1MS => (IKTGLSection) new G1MSkeleton(dataBlock, ignoreVersion, sectionHeader),
                    DataType.G1MF => new G1MFormat(dataBlock, ignoreVersion, sectionHeader),
                    DataType.G1MG => new G1MGeometry(dataBlock, ignoreVersion, sectionHeader),
                    DataType.G1MM => new G1MMatrix(dataBlock, ignoreVersion, sectionHeader),
                    DataType.EXTR => new G1Extra(dataBlock, ignoreVersion, sectionHeader),
                    _ => new G1MStub(dataBlock, sectionHeader)
                };

                Sections.Add(section);
            }
        }