diff --git a/Runtime/Scripts/GLTFSceneExporter.cs b/Runtime/Scripts/GLTFSceneExporter.cs index 6ac674e32..3c294161c 100644 --- a/Runtime/Scripts/GLTFSceneExporter.cs +++ b/Runtime/Scripts/GLTFSceneExporter.cs @@ -249,6 +249,19 @@ private struct ImageInfo public bool canBeExportedFromDisk; } + private struct FileInfo + { + public Stream stream; + public string uniqueFileName; + } + + public struct ExportFileResult + { + public string uri; + public string mimeType; + public BufferViewId bufferView; + } + public IReadOnlyList RootTransforms => _rootTransforms; private Transform[] _rootTransforms; @@ -256,6 +269,8 @@ private struct ImageInfo private BufferId _bufferId; private GLTFBuffer _buffer; private List _imageInfos; + private List _fileInfos; + private HashSet _fileNames; private List _textures; private Dictionary _exportedMaterials; private bool _shouldUseInternalBufferForImages; @@ -509,6 +524,8 @@ public GLTFSceneExporter(Transform[] rootTransforms, ExportOptions options) }; _imageInfos = new List(); + _fileInfos = new List(); + _fileNames = new HashSet(); _exportedMaterials = new Dictionary(); _textures = new List(); @@ -551,6 +568,7 @@ public void SaveGLB(string path, string fileName) if (!_shouldUseInternalBufferForImages) { ExportImages(path); + ExportFiles(path); } } @@ -754,6 +772,8 @@ public void SaveGLTFandBin(string path, string fileName, bool exportTextures = t if (exportTextures) ExportImages(path); + + ExportFiles(path); gltfWriteOutMarker.End(); exportGltfMarker.End(); @@ -1066,6 +1086,53 @@ private void FilterPrimitives(Transform transform, out GameObject[] primitives, // && ContainsValidRenderer(gameObject); // } + public ExportFileResult ExportFile(string fileName, string mimeType, Stream stream) { + if (_shouldUseInternalBufferForImages) { + byte[] data = new byte[stream.Length]; + stream.Read(data, 0, (int)stream.Length); + stream.Close(); + + return new ExportFileResult { + bufferView = this.ExportBufferView(data), + mimeType = mimeType, + }; + } else { + var uniqueFileName = GetUniqueName(_fileNames, fileName); + + _fileNames.Add(uniqueFileName); + + _fileInfos.Add( + new FileInfo { + stream = stream, + uniqueFileName = uniqueFileName, + } + ); + + return new ExportFileResult { + uri = uniqueFileName, + }; + } + } + + private void ExportFiles(string outputPath) + { + for (int i = 0; i < _fileInfos.Count; ++i) + { + var fileInfo = _fileInfos[i]; + + var fileOutputPath = Path.Combine(outputPath, fileInfo.uniqueFileName); + + var dir = Path.GetDirectoryName(fileOutputPath); + if (!Directory.Exists(dir) && dir != null) + Directory.CreateDirectory(dir); + + var outputStream = File.Create(fileOutputPath); + fileInfo.stream.Seek(0, SeekOrigin.Begin); + fileInfo.stream.CopyTo(outputStream); + outputStream.Close(); + } + } + private void ExportAnimation() { for (int i = 0; i < _animatedNodes.Count; ++i) diff --git a/Runtime/Scripts/SceneExporter/ExporterAccessors.cs b/Runtime/Scripts/SceneExporter/ExporterAccessors.cs index 36af29ce7..1c2edc415 100644 --- a/Runtime/Scripts/SceneExporter/ExporterAccessors.cs +++ b/Runtime/Scripts/SceneExporter/ExporterAccessors.cs @@ -1175,6 +1175,14 @@ private AccessorId ExportAccessor(Color[] arr, bool exportAlphaChannel) return id; } + public BufferViewId ExportBufferView(byte[] bytes) { + AlignToBoundary(_bufferWriter.BaseStream, 0x00); + uint byteOffset = CalculateAlignment((uint)_bufferWriter.BaseStream.Position, 4); + _bufferWriter.Write(bytes); + uint byteLength = CalculateAlignment((uint)_bufferWriter.BaseStream.Position - byteOffset, 4); + return ExportBufferView((uint)byteOffset, (uint)byteLength); + } + private BufferViewId ExportBufferView(uint byteOffset, uint byteLength, uint byteStride = 0) { var bufferView = new BufferView