diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs index 782a6fa40..59c88990b 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfData.cs @@ -314,18 +314,18 @@ namespace UniGLTF return result; } - public ArraySegment GetBytesFromImage(int imageIndex) + public (ArraySegment binary, string mimeType)? GetBytesFromImage(int imageIndex) { - if (imageIndex < 0 || imageIndex >= GLTF.images.Count) return new ArraySegment(); + if (imageIndex < 0 || imageIndex >= GLTF.images.Count) return default; var image = GLTF.images[imageIndex]; if (string.IsNullOrEmpty(image.uri)) { - return GetBytesFromBufferView(image.bufferView); + return (GetBytesFromBufferView(image.bufferView), image.mimeType); } else { - return GetBytesFromUri(image.uri); + return (GetBytesFromUri(image.uri), image.mimeType); } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs index e16b1fbd9..bd422a7a0 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfUnlitMaterialImporter.cs @@ -44,7 +44,7 @@ namespace UniGLTF { var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); - var (key, textureParam) = GltfTextureImporter.CreateSRGB(data, + var (key, textureParam) = GltfTextureImporter.CreateSrgb(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); textureSlots.Add("_MainTex", textureParam); } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs index ca963e882..5d7ab1dfa 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfPbrTextureImporter.cs @@ -54,7 +54,7 @@ namespace UniGLTF public static (SubAssetKey, TextureDescriptor) BaseColorTexture(GltfData data, glTFMaterial src) { var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.pbrMetallicRoughness.baseColorTexture); - return GltfTextureImporter.CreateSRGB(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); + return GltfTextureImporter.CreateSrgb(data, src.pbrMetallicRoughness.baseColorTexture.index, offset, scale); } public static (SubAssetKey, TextureDescriptor) StandardTexture(GltfData data, glTFMaterial src) @@ -84,7 +84,7 @@ namespace UniGLTF public static (SubAssetKey, TextureDescriptor) EmissiveTexture(GltfData data, glTFMaterial src) { var (offset, scale) = GltfTextureImporter.GetTextureOffsetAndScale(src.emissiveTexture); - return GltfTextureImporter.CreateSRGB(data, src.emissiveTexture.index, offset, scale); + return GltfTextureImporter.CreateSrgb(data, src.emissiveTexture.index, offset, scale); } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureImporter.cs index de62bb739..c5d6b6614 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/GltfTextureImporter.cs @@ -11,32 +11,48 @@ namespace UniGLTF /// public static class GltfTextureImporter { - public static Byte[] ToArray(ArraySegment bytes) + /// + /// glTF の Texture が存在せず Image のみのものを、Texture として扱いたい場合の関数. + /// + public static (SubAssetKey, TextureDescriptor) CreateSrgbFromOnlyImage(GltfData data, int imageIndex, string uniqueName, string uri) { - if (bytes.Array == null) - { - return new byte[] { }; - } - else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length) - { - return bytes.Array; - } - else - { - Byte[] result = new byte[bytes.Count]; - Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length); - return result; - } + var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, uniqueName, uri); + var texDesc = new TextureDescriptor( + uniqueName, + string.Empty, + uri, + Vector2.zero, + Vector2.one, + default, + TextureImportTypes.sRGB, + default, + default, + () => + { + var imageBytes = data.GetBytesFromImage(imageIndex); + return Task.FromResult<(byte[], string)?>((ToArray(imageBytes?.binary ?? default), null)); + }, + default, default, default, default, default); + return (texDesc.SubAssetKey, texDesc); } - public static (SubAssetKey, TextureDescriptor) CreateSRGB(GltfData data, int textureIndex, Vector2 offset, Vector2 scale) + public static (SubAssetKey, TextureDescriptor) CreateSrgb(GltfData data, int textureIndex, Vector2 offset, Vector2 scale) { var gltfTexture = data.GLTF.textures[textureIndex]; var gltfImage = data.GLTF.images[gltfTexture.source]; var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfTexture.name, gltfImage.uri); var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex); - GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex))); - var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default); + var param = new TextureDescriptor( + name, + gltfImage.GetExt(), + gltfImage.uri, + offset, scale, + sampler, + TextureImportTypes.sRGB, + default, + default, + () => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)), + default, default, default, default, default); return (param.SubAssetKey, param); } @@ -46,8 +62,18 @@ namespace UniGLTF var gltfImage = data.GLTF.images[gltfTexture.source]; var name = TextureImportName.GetUnityObjectName(TextureImportTypes.Linear, gltfTexture.name, gltfImage.uri); var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex); - GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex))); - var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.Linear, default, default, getTextureBytesAsync, default, default, default, default, default); + var param = new TextureDescriptor( + name, + gltfImage.GetExt(), + gltfImage.uri, + offset, + scale, + sampler, + TextureImportTypes.Linear, + default, + default, + () => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)), + default, default, default, default, default); return (param.SubAssetKey, param); } @@ -57,8 +83,18 @@ namespace UniGLTF var gltfImage = data.GLTF.images[gltfTexture.source]; var name = TextureImportName.GetUnityObjectName(TextureImportTypes.NormalMap, gltfTexture.name, gltfImage.uri); var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex); - GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, textureIndex))); - var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.NormalMap, default, default, getTextureBytesAsync, default, default, default, default, default); + var param = new TextureDescriptor( + name, + gltfImage.GetExt(), + gltfImage.uri, + offset, + scale, + sampler, + TextureImportTypes.NormalMap, + default, + default, + () => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)), + default, default, default, default, default); return (param.SubAssetKey, param); } @@ -73,7 +109,7 @@ namespace UniGLTF var gltfTexture = data.GLTF.textures[metallicRoughnessTextureIndex.Value]; name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri); sampler = TextureSamplerUtil.CreateSampler(data.GLTF, metallicRoughnessTextureIndex.Value); - getMetallicRoughnessAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, metallicRoughnessTextureIndex.Value))); + getMetallicRoughnessAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, metallicRoughnessTextureIndex.Value)); } GetTextureBytesAsync getOcclusionAsync = default; @@ -85,10 +121,22 @@ namespace UniGLTF name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri); } sampler = TextureSamplerUtil.CreateSampler(data.GLTF, occlusionTextureIndex.Value); - getOcclusionAsync = () => Task.FromResult(ToArray(GetImageBytesFromTextureIndex(data, occlusionTextureIndex.Value))); + getOcclusionAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, occlusionTextureIndex.Value)); } - var texDesc = new TextureDescriptor(name, ".png", null, offset, scale, sampler, TextureImportTypes.StandardMap, metallicFactor, roughnessFactor, getMetallicRoughnessAsync, getOcclusionAsync, default, default, default, default); + var texDesc = new TextureDescriptor( + name, + ".png", + null, + offset, + scale, + sampler, + TextureImportTypes.StandardMap, + metallicFactor, + roughnessFactor, + getMetallicRoughnessAsync, + getOcclusionAsync, + default, default, default, default); return (texDesc.SubAssetKey, texDesc); } @@ -124,7 +172,7 @@ namespace UniGLTF return (offset, scale); } - public static ArraySegment GetImageBytesFromTextureIndex(GltfData data, int textureIndex) + public static (byte[] binary, string mimeType)? GetImageBytesFromTextureIndex(GltfData data, int textureIndex) { if (Application.isPlaying) { @@ -140,20 +188,45 @@ namespace UniGLTF } } - return data.GetBytesFromImage(imageIndex); + if (!imageIndex.HasValue) return default; + + var imageBytes = data.GetBytesFromImage(imageIndex.Value); + return (ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType); } else { // NOTE: Editor の場合は通常通り読み込む. - return data.GetBytesFromImage(GetImageIndexFromTexture(data, textureIndex)); + var imageIndex = GetImageIndexFromTexture(data, textureIndex); + if (!imageIndex.HasValue) return default; + + var imageBytes = data.GetBytesFromImage(imageIndex.Value); + return (ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType); } } - private static int GetImageIndexFromTexture(GltfData data, int textureIndex) + private static int? GetImageIndexFromTexture(GltfData data, int textureIndex) { - if (textureIndex < 0 || textureIndex >= data.GLTF.textures.Count) return -1; + if (textureIndex < 0 || textureIndex >= data.GLTF.textures.Count) return default; return data.GLTF.textures[textureIndex].source; } + + private static byte[] ToArray(ArraySegment bytes) + { + if (bytes.Array == null) + { + return new byte[] { }; + } + else if (bytes.Offset == 0 && bytes.Count == bytes.Array.Length) + { + return bytes.Array; + } + else + { + var result = new byte[bytes.Count]; + Buffer.BlockCopy(bytes.Array, bytes.Offset, result, 0, result.Length); + return result; + } + } } } diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index 889dd7892..ced6f815d 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -292,7 +292,7 @@ namespace VRM meta.Title = gltfMeta.title; if (gltfMeta.texture >= 0) { - var (key, param) = GltfTextureImporter.CreateSRGB(Data, gltfMeta.texture, Vector2.zero, Vector2.one); + var (key, param) = GltfTextureImporter.CreateSrgb(Data, gltfMeta.texture, Vector2.zero, Vector2.one); meta.Thumbnail = await TextureFactory.GetTextureAsync(param, awaitCaller) as Texture2D; } meta.AllowedUser = gltfMeta.allowedUser; diff --git a/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs index de8dd3622..52485a320 100644 --- a/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs +++ b/Assets/VRM/Runtime/IO/VRMMToonTextureImporter.cs @@ -36,7 +36,7 @@ namespace VRM texture = GltfTextureImporter.CreateNormal(data, textureIdx, offset, scale); break; default: - texture = GltfTextureImporter.CreateSRGB(data, textureIdx, offset, scale); + texture = GltfTextureImporter.CreateSrgb(data, textureIdx, offset, scale); break; } return true; diff --git a/Assets/VRM/Runtime/IO/VrmTextureDescriptorGenerator.cs b/Assets/VRM/Runtime/IO/VrmTextureDescriptorGenerator.cs index 4e484f878..047d866cb 100644 --- a/Assets/VRM/Runtime/IO/VrmTextureDescriptorGenerator.cs +++ b/Assets/VRM/Runtime/IO/VrmTextureDescriptorGenerator.cs @@ -69,7 +69,7 @@ namespace VRM { if (vrm.meta.texture > -1) { - texture = GltfTextureImporter.CreateSRGB(data, vrm.meta.texture, Vector2.zero, Vector2.one); + texture = GltfTextureImporter.CreateSrgb(data, vrm.meta.texture, Vector2.zero, Vector2.one); return true; } diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs index 7390ded09..edbb26db1 100644 --- a/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10MToonTextureImporter.cs @@ -151,7 +151,7 @@ namespace UniVRM10 try { var (offset, scale) = GetTextureOffsetAndScale(info); - pair = GltfTextureImporter.CreateSRGB(data, info.index, offset, scale); + pair = GltfTextureImporter.CreateSrgb(data, info.index, offset, scale); return true; } catch (NullReferenceException) diff --git a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs index c9de0bd5e..b6e55d56c 100644 --- a/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs +++ b/Assets/VRM10/Runtime/IO/Texture/Vrm10TextureDescriptorGenerator.cs @@ -106,18 +106,7 @@ namespace UniVRM10 } var uniqueName = GlbLowLevelParser.FixNameUnique(used, imageName); - var objectName = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, uniqueName, gltfImage.uri); - - GetTextureBytesAsync getThumbnailImageBytesAsync = () => - { - var bytes = data.GetBytesFromImage(imageIndex); - return Task.FromResult(GltfTextureImporter.ToArray(bytes)); - }; - var texDesc = new TextureDescriptor(objectName, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default, - getThumbnailImageBytesAsync, default, default, - default, default, default - ); - value = (texDesc.SubAssetKey, texDesc); + value = GltfTextureImporter.CreateSrgbFromOnlyImage(data, imageIndex, uniqueName, gltfImage.uri); return true; } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/DeserializingTextureInfo.cs b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/DeserializingTextureInfo.cs index 8907bb794..f7ce5d093 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/DeserializingTextureInfo.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/DeserializingTextureInfo.cs @@ -12,6 +12,11 @@ namespace VRMShaders /// public byte[] ImageData { get; } + /// + /// Texture の mimeType + /// + public string DataMimeType { get; } + /// /// Texture に求められる色空間 /// @@ -37,9 +42,10 @@ namespace VRMShaders /// public TextureWrapMode WrapModeV { get; } - internal DeserializingTextureInfo(byte[] imageData, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV) + internal DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV) { ImageData = imageData; + DataMimeType = dataMimeType; ColorSpace = colorSpace; UseMipmap = useMipmap; FilterMode = filterMode; @@ -47,9 +53,10 @@ namespace VRMShaders WrapModeV = wrapModeV; } - internal DeserializingTextureInfo(byte[] imageData, ColorSpace colorSpace, SamplerParam samplerParam) + internal DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, SamplerParam samplerParam) { ImageData = imageData; + DataMimeType = dataMimeType; ColorSpace = colorSpace; UseMipmap = samplerParam.EnableMipMap; FilterMode = samplerParam.FilterMode; diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureDescriptor.cs b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureDescriptor.cs index 218ebcad6..f8fd75ff4 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureDescriptor.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureDescriptor.cs @@ -13,7 +13,7 @@ namespace VRMShaders /// File.WriteAllBytes /// /// - public delegate Task GetTextureBytesAsync(); + public delegate Task<(byte[] binary, string mimeType)?> GetTextureBytesAsync(); /// /// 入力 glTF ファイルを Import した結果生成される、UnityEngine.Texture のアセット 1 つを確定させる Import 情報。 diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureFactory.cs b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureFactory.cs index 30f1ac9d8..68a80c458 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureFactory.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/Texture/Importer/TextureFactory.cs @@ -80,7 +80,7 @@ namespace VRMShaders // https://docs.unity3d.com/2018.4/Documentation/Manual/StandardShaderMaterialParameterNormalMap.html var data0 = await texDesc.Index0(); var rawTexture = await TextureDeserializer.LoadTextureAsync( - new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler), + new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler), awaitCaller); rawTexture.name = subAssetKey.Name; _textureCache.Add(subAssetKey, rawTexture); @@ -96,14 +96,14 @@ namespace VRMShaders { var data0 = await texDesc.Index0(); metallicRoughnessTexture = await TextureDeserializer.LoadTextureAsync( - new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler), + new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler), awaitCaller); } if (texDesc.Index1 != null) { var data1 = await texDesc.Index1(); occlusionTexture = await TextureDeserializer.LoadTextureAsync( - new DeserializingTextureInfo(data1, ColorSpace.Linear, texDesc.Sampler), + new DeserializingTextureInfo(data1?.binary, data1?.mimeType, ColorSpace.Linear, texDesc.Sampler), awaitCaller); } @@ -123,7 +123,7 @@ namespace VRMShaders { var data0 = await texDesc.Index0(); var rawTexture = await TextureDeserializer.LoadTextureAsync( - new DeserializingTextureInfo(data0, ColorSpace.sRGB, texDesc.Sampler), + new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.sRGB, texDesc.Sampler), awaitCaller); rawTexture.name = subAssetKey.Name; _textureCache.Add(subAssetKey, rawTexture); @@ -133,7 +133,7 @@ namespace VRMShaders { var data0 = await texDesc.Index0(); var rawTexture = await TextureDeserializer.LoadTextureAsync( - new DeserializingTextureInfo(data0, ColorSpace.Linear, texDesc.Sampler), + new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler), awaitCaller); rawTexture.name = subAssetKey.Name; _textureCache.Add(subAssetKey, rawTexture);