Separate Vrm10 Texture Enumerator

This commit is contained in:
Masataka SUMI
2021-05-07 20:34:01 +09:00
parent 14151cb12d
commit db336970c9
7 changed files with 99 additions and 70 deletions

View File

@@ -68,7 +68,7 @@ namespace UniVRM10
case Tabs.Materials:
if (m_parser != null)
{
EditorMaterial.OnGUI(m_importer, m_parser, Vrm10MaterialImporter.EnumerateAllTexturesDistinct);
EditorMaterial.OnGUI(m_importer, m_parser, Vrm10TextureEnumerator.EnumerateAllTexturesDistinct);
}
break;

View File

@@ -99,7 +99,7 @@ namespace UniVRM10
using (var loader = new Vrm10Importer(parser, externalObjectMap))
{
// settings TextureImporters
foreach (var (key, textureInfo) in Vrm10MaterialImporter.EnumerateAllTexturesDistinct(parser))
foreach (var (key, textureInfo) in Vrm10TextureEnumerator.EnumerateAllTexturesDistinct(parser))
{
VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7fe27001b96146d3bbc53044ff91b536
timeCreated: 1620374936

View File

@@ -0,0 +1,90 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using UniGLTF;
using UnityEngine;
using VRMShaders;
namespace UniVRM10
{
public static class Vrm10TextureEnumerator
{
/// <summary>
/// glTF 全体で使うテクスチャーをユニークになるように列挙する
/// </summary>
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
{
throw new System.Exception("not vrm");
}
var usedTextures = new HashSet<SubAssetKey>();
// Thumbnail Texture referenced by VRM Meta.
if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey key, TextureImportParam) thumbnail))
{
if (usedTextures.Add(thumbnail.key))
{
yield return thumbnail;
}
}
// Textures referenced by Materials.
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
var param = Vrm10MaterialImporter.GetMaterialParam(parser, i);
foreach (var (key, value) in param.EnumerateSubAssetKeyValue())
{
if (usedTextures.Add(key))
{
yield return (key, value);
}
}
}
}
/// <summary>
/// VRM-1 の thumbnail テクスチャー。gltf.textures ではなく gltf.images の参照であることに注意(sampler等の設定が無い)
/// </summary>
public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out (SubAssetKey, TextureImportParam) value)
{
if (vrm?.Meta?.ThumbnailImage == null)
{
value = default;
return false;
}
var imageIndex = vrm.Meta.ThumbnailImage.Value;
var gltfImage = parser.GLTF.images[imageIndex];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri);
GetTextureBytesAsync getThumbnailImageBytesAsync = () =>
{
var bytes = parser.GLTF.GetImageBytes(parser.Storage, imageIndex);
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
};
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
getThumbnailImageBytesAsync, default, default,
default, default, default
);
var key = new SubAssetKey(typeof(Texture2D), name);
value = (key, param);
return true;
}
/// <summary>
/// Material によって参照されている Texture を Enumerate する.
/// まず VRM Material だと仮定して処理し, 失敗すれば glTF Material だとして処理する.
/// </summary>
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateTexturesReferencedByMaterials(GltfParser parser, int i)
{
// VRM
// Fallback to GLTF
foreach (var kv in GltfTextureEnumerator.EnumerateTexturesReferencedByMaterials(parser, i))
{
yield return kv;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7763318be4064ecba712dcc012dd1cb1
timeCreated: 1620374912

View File

@@ -280,7 +280,7 @@ namespace UniVRM10
{
m_meta.Authors.AddRange(src.Authors);
}
if (Vrm10MaterialImporter.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv))
if (Vrm10TextureEnumerator.TryGetMetaThumbnailTextureImportParam(Parser, vrm, out (SubAssetKey, VRMShaders.TextureImportParam Param) kv))
{
var texture = await TextureFactory.GetTextureAsync(kv.Param);
if (texture != null)

View File

@@ -176,72 +176,5 @@ namespace UniVRM10
}
return param;
}
/// <summary>
/// VRM-1 の thumbnail テクスチャー。gltf.textures ではなく gltf.images の参照であることに注意(sampler等の設定が無い)
///
/// MToonとは無関係だがとりあえずここに
/// </summary>
/// <param name="parser"></param>
/// <param name="vrm"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool TryGetMetaThumbnailTextureImportParam(GltfParser parser, UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm, out (SubAssetKey, TextureImportParam) value)
{
if (vrm?.Meta == null || !vrm.Meta.ThumbnailImage.HasValue)
{
value = default;
return false;
}
// thumbnail
var imageIndex = vrm.Meta.ThumbnailImage.Value;
var gltfImage = parser.GLTF.images[imageIndex];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfImage.name, gltfImage.uri);
GetTextureBytesAsync getBytesAsync = () =>
{
var bytes = parser.GLTF.GetImageBytes(parser.Storage, imageIndex);
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
};
var param = new TextureImportParam(name, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
getBytesAsync, default, default,
default, default, default
);
var key = new SubAssetKey(typeof(Texture2D), name);
value = (key, param);
return true;
}
/// <summary>
/// glTF 全体で使うテクスチャーをユニークになるように列挙する
/// </summary>
/// <param name="parser"></param>
/// <returns></returns>
public static IEnumerable<(SubAssetKey, TextureImportParam)> EnumerateAllTexturesDistinct(GltfParser parser)
{
if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
{
throw new System.Exception("not vrm");
}
if (TryGetMetaThumbnailTextureImportParam(parser, vrm, out (SubAssetKey, TextureImportParam) thumbnail))
{
yield return thumbnail;
}
var used = new HashSet<SubAssetKey>();
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
{
var param = GetMaterialParam(parser, i);
foreach (var (key, value) in param.EnumerateSubAssetKeyValue())
{
if (used.Add(key))
{
yield return (key, value);
}
}
}
}
}
}