/// <summary> /// Write to G1M span using just SectionsRoot /// </summary> /// <returns></returns> public Span <byte> WriteFromRoot() { var sectionHeaderSize = SizeHelper.SizeOf <ResourceSectionHeader>(); var size = SizeHelper.SizeOf <ModelHeader>() + sectionHeaderSize + SectionRoot.Sections.Sum(x => x.Length); var buffer = new Span <byte>(new byte[size]); var modelSectionHeader = Section; modelSectionHeader.Size = size; MemoryMarshal.Write(buffer, ref modelSectionHeader); var offset = sectionHeaderSize; var modelHeader = new ModelHeader { HeaderSize = sectionHeaderSize + SizeHelper.SizeOf <ModelHeader>(), Reserved = 0, SectionCount = SectionRoot.Sections.Count }; MemoryMarshal.Write(buffer.Slice(offset), ref modelHeader); offset = modelHeader.HeaderSize; foreach (var data in SectionRoot.Sections) { data.Span.CopyTo(buffer.Slice(offset)); offset += data.Length; } return(buffer); }
/// <summary> /// Loads all transforms from the <paramref name="ctx"/> that pass the <paramref name="isTransformTagAccepted"/> test, /// applies them sequentially to the <paramref name="srcView"/>, and returns the resulting data view. /// If there are no transforms in <paramref name="ctx"/> that are accepted, returns the original <paramref name="srcView"/>. /// The difference from the <c>Create</c> method above is that: /// - it doesn't wrap the results into a loader, just returns the last transform in the chain. /// - it accepts <see cref="IDataView"/> as input, not necessarily a loader. /// - it throws away the tag information. /// - it doesn't throw if the context is not representing a <see cref="LegacyCompositeDataLoader"/>: in this case it's assumed that no transforms /// meet the test, and the <paramref name="srcView"/> is returned. /// Essentially, this is a helper method for the LoadTransform class. /// </summary> public static IDataView LoadSelectedTransforms(ModelLoadContext ctx, IDataView srcView, IHostEnvironment env, Func<string, bool> isTransformTagAccepted) { Contracts.CheckValue(env, nameof(env)); var h = env.Register(RegistrationName); h.CheckValue(ctx, nameof(ctx)); h.Check(ctx.Reader.BaseStream.Position == ctx.FpMin + ctx.Header.FpModel); var ver = GetVersionInfo(); if (ctx.Header.ModelSignature != ver.ModelSignature) { using (var ch = h.Start("ModelCheck")) { ch.Info("The data model doesn't contain transforms."); } return srcView; } ModelHeader.CheckVersionInfo(ref ctx.Header, ver); h.CheckValue(srcView, nameof(srcView)); h.CheckValue(isTransformTagAccepted, nameof(isTransformTagAccepted)); // *** Binary format *** // int: sizeof(Float) // int: number of transforms // foreach transform: (starting from version VersionAddedTags) // string: tag // string: args string int cbFloat = ctx.Reader.ReadInt32(); h.CheckDecode(cbFloat == sizeof(float)); int cxf = ctx.Reader.ReadInt32(); h.CheckDecode(cxf >= 0); bool hasTags = ctx.Header.ModelVerReadable >= VersionAddedTags; var curView = srcView; for (int i = 0; i < cxf; i++) { string tag = ""; if (hasTags) { tag = ctx.LoadNonEmptyString(); ctx.LoadStringOrNull(); // ignore the args string } if (!isTransformTagAccepted(tag)) continue; IDataTransform xf; ctx.LoadModel<IDataTransform, SignatureLoadDataTransform>(env, out xf, string.Format(TransformDirTemplate, i), curView); curView = xf; } return curView; }
public void Parse(Stream input) { using (BinaryReader reader = new BinaryReader(input)) { Header = reader.Read <ModelHeader>(); if (Header.MaterialOffset > 0) { input.Position = Header.MaterialOffset; Materials = reader.ReadArray <ulong>(Header.MaterialCount); } } }
public Model(ModelHeader header, BinaryReader reader) { this.Header = header; var start = reader.BaseStream.Position; reader.BaseStream.Position = start + header.MeshIndex; Meshes = new Mesh[header.MeshCount]; for (var i = 0; i < header.MeshCount; i++) { var modelHeader = reader.ReadStruct <MeshHeader>(); Meshes[i] = new Mesh(modelHeader, reader); } }
public override void WriteModelStart(ModelHeader header) { this.WriteStringValue(header.ModelName); this.WriteIntegerValue(header.PropertyCount); }