/// <summary> /// Creates a complete clone of this <see cref="ModelRoot"/> instance. /// </summary> /// <returns>A new <see cref="ModelRoot"/> instance.</returns> /// <remarks> /// Deep cloning is performed as a brute force operation; by serializing /// the whole model to GLTF into memory, and then deserializing it back to DOM. /// </remarks> public ModelRoot DeepClone() { // prepare the in-memory temporary storage var dict = new Dictionary <string, ArraySegment <Byte> >(); var wcontext = WriteContext .CreateFromDictionary(dict) .WithDeepCloneSettings(); System.Diagnostics.Debug.Assert(wcontext._NoCloneWatchdog, "invalid clone settings"); // write the model to the temporary storage wcontext.WriteTextSchema2("deepclone", this); // restore the model from the temporary storage var rcontext = ReadContext.CreateFromDictionary(dict, wcontext._UpdateSupportedExtensions); rcontext.Validation = Validation.ValidationMode.Skip; var cloned = rcontext.ReadSchema2("deepclone.gltf"); // Restore MemoryImage source URIs (they're not cloned as part of the serialization) foreach (var srcImg in this.LogicalImages) { var dstImg = cloned.LogicalImages[srcImg.LogicalIndex]; var img = dstImg.Content; dstImg.Content = new Memory.MemoryImage(img._GetBuffer(), srcImg.Content.SourcePath); } return(cloned); }
/// <summary> /// Called internally by the serializer when the buffer content is to be written as an external file /// </summary> /// <param name="writer">The satellite asset writer</param> /// <param name="satelliteUri">A local satellite URI</param> internal void _WriteToSatellite(WriteContext writer, string satelliteUri) { writer.WriteAllBytesToEnd(satelliteUri, new ArraySegment <byte>(_Content.GetPaddedContent())); this._uri = Uri.EscapeUriString(satelliteUri); this._byteLength = _Content.Length; }
internal void _PrepareBuffersForSatelliteWriting(WriteContext context, string baseName) { // setup all buffers to be written as satellite files for (int i = 0; i < this._buffers.Count; ++i) { var buffer = this._buffers[i]; var bname = this._buffers.Count != 1 ? $"{baseName}_{i}.bin" : $"{baseName}.bin"; buffer._WriteToSatellite(context, bname); } }
public static WriteContext Create(FileWriterCallback fileCallback) { Guard.NotNull(fileCallback, nameof(fileCallback)); var context = new WriteContext(fileCallback) { _UpdateSupportedExtensions = true }; return(context); }
/// <summary> /// Writes this <see cref="MODEL"/> to a file in GLTF format. /// </summary> /// <param name="filePath">A valid file path to write to.</param> /// <param name="settings">Optional settings.</param> /// <remarks> /// Satellite files like buffers and images are also saved with the file name formatted as "FILE_{Index}.EXT". /// </remarks> public void SaveGLTF(string filePath, WriteSettings settings = null) { Guard.FilePathMustBeValid(filePath, nameof(filePath)); var context = WriteContext .CreateFromFile(filePath) .WithSettingsFrom(settings); var name = Path.GetFileNameWithoutExtension(filePath); context.WriteTextSchema2(name, this); }
/// <summary> /// Writes this <see cref="MODEL"/> to a <see cref="Stream"/> in GLB format. /// </summary> /// <param name="stream">A <see cref="Stream"/> open for writing.</param> /// <param name="settings">Optional settings.</param> public void WriteGLB(Stream stream, WriteSettings settings = null) { Guard.NotNull(stream, nameof(stream)); Guard.IsTrue(stream.CanWrite, nameof(stream)); var context = WriteContext .CreateFromStream(stream) .WithSettingsFrom(settings); if (settings != null) { // override settings with required values for GLB writing. context.MergeBuffers = true; context.ImageWriting = ResourceWriteMode.Default; } context.WriteBinarySchema2("model", this); }
internal void _PrepareImagesForWriting(WriteContext context, string baseName, ResourceWriteMode rmode) { if (context.ImageWriting != ResourceWriteMode.Default) { rmode = context.ImageWriting; } // setup all images to be written to the appropiate location. for (int i = 0; i < this._images.Count; ++i) { var image = this._images[i]; if (rmode != ResourceWriteMode.SatelliteFile) { image._WriteToInternal(); } else { var iname = this._images.Count != 1 ? $"{baseName}_{i}" : $"{baseName}"; image._WriteToSatellite(context, iname); } } }