TextureImportParam.ExtractKey

This commit is contained in:
ousttrue
2021-03-25 14:49:56 +09:00
parent fd198ac10d
commit f2b82200f1
5 changed files with 315 additions and 6 deletions

View File

@@ -1,10 +1,37 @@
using System.Collections.Generic;
using VRMShaders;
namespace UniGLTF
{
public delegate IEnumerable<TextureImportParam> TextureEnumerator(GltfParser parser);
/// <summary>
/// Texture 生成に関して
/// Runtimeは LoadImage するだけだが、Editor時には Asset 化するにあたって続きの処理がある。
///
/// * (gltf/glb/vrm-1): AssetImporterContext.AddObjectToAsset(SubAsset)
/// * (gltf/glb/vrm-1): ScriptedImporter.GetExternalObjectMap(Extracted)
/// * (vrm-0): (Extracted) ScriptedImporter では無いので ScriptedImporter.AddRemap が無い
///
/// Extract は外部ファイルに png/jpg のバイト列を出力して、TextureImporter を設定すること。ScriptedImporter.AddRemap
/// Extracted は、
///
/// ファイル名もしくはSubAsset名を介してテクスチャーアセットにアクセスるので、文字列をユニークなキーとしてテクスチャーを識別できる必要がある。
/// 基本的に、gltf.textures と Texture2D が1対1に対応するので、 gltfTexture.name のユニーク性を確保した上で
/// これを用いればよいが以下の例外がある。
///
/// * PBR の MetallicSmoothness と Occlusion が合体する場合
/// * (gltf)外部テクスチャーファイルの uri 参照が同じになる場合(同じイメージファイルが異なるテクスチャー設定を保持するケースをサポートしない)
/// * 異なる gltfTexture.source が 同じ gltfImage を参照する場合
/// * 異なる gltfImage.uri が 同じ ファイルを参照する場合
///
/// 例外に対処した上で、ユニークなテクスチャー生成情報を列挙するのが
///
/// GltfTextureEnumerator.Enumerate
///
/// である。
/// </summary>
public static class GltfTextureEnumerator
{
public static IEnumerable<TextureImportParam> EnumerateTextures(GltfParser parser, glTFMaterial m)
@@ -54,12 +81,12 @@ namespace UniGLTF
public static IEnumerable<TextureImportParam> Enumerate(GltfParser parser)
{
var used = new HashSet<TextureImportParam>();
var used = new HashSet<string>();
foreach (var material in parser.GLTF.materials)
{
foreach (var textureInfo in EnumerateTextures(parser, material))
{
if(used.Add(textureInfo)){
if(used.Add(textureInfo.ExtractKey)){
yield return textureInfo;
}
}

View File

@@ -0,0 +1,242 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace UniGLTF
{
public class TextureEnumerateTests
{
static glTF TwoTexture()
{
return new glTF
{
images = new List<glTFImage>
{
new glTFImage{
name = "image_0",
mimeType = "image/png",
},
new glTFImage{
name = "image_1",
mimeType = "image/png",
},
},
textures = new List<glTFTexture>
{
new glTFTexture{
name = "texture_0",
source = 0,
},
new glTFTexture{
name = "texture_1",
source = 1,
},
},
materials = new List<glTFMaterial>
{
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 1,
}
}
},
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
},
};
}
static glTF TwoTextureOneUri()
{
return new glTF
{
images = new List<glTFImage>
{
new glTFImage{
name = "image_0",
mimeType = "image/png",
uri = "some.png",
},
new glTFImage{
name = "image_1",
mimeType = "image/png",
uri = "some.png",
},
},
textures = new List<glTFTexture>
{
new glTFTexture{
name = "texture_0",
source = 0,
},
new glTFTexture{
name = "texture_1",
source = 1,
},
},
materials = new List<glTFMaterial>
{
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 1,
}
}
},
},
};
}
static glTF TwoTextureOneImage()
{
return new glTF
{
images = new List<glTFImage>
{
new glTFImage{
name = "image_0",
mimeType = "image/png",
uri = "some.png",
},
},
textures = new List<glTFTexture>
{
new glTFTexture{
name = "texture_0",
source = 0,
},
new glTFTexture{
name = "texture_1",
source = 0,
},
},
materials = new List<glTFMaterial>
{
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 0,
}
}
},
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
baseColorTexture = new glTFMaterialBaseColorTextureInfo{
index = 1,
}
}
},
},
};
}
static glTF CombineMetallicSmoothOcclusion()
{
return new glTF
{
images = new List<glTFImage>
{
new glTFImage{
name = "image_0",
mimeType = "image/png",
uri = "metallicSmoothness.png",
},
new glTFImage{
name = "image_1",
mimeType = "image/png",
uri = "occlusion.png",
},
},
textures = new List<glTFTexture>
{
new glTFTexture{
name = "texture_0",
source = 0,
},
new glTFTexture{
name = "texture_1",
source = 1,
},
},
materials = new List<glTFMaterial>
{
new glTFMaterial{
pbrMetallicRoughness = new glTFPbrMetallicRoughness{
metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo{
index = 0,
}
},
occlusionTexture = new glTFMaterialOcclusionTextureInfo{
index = 1,
}
},
},
};
}
/// <summary>
/// Test uniqueness
/// </summary>
[Test]
public void TextureEnumerationTest()
{
{
var parser = new GltfParser
{
GLTF = TwoTexture(),
};
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
Assert.AreEqual(2, items.Length);
}
{
var parser = new GltfParser
{
GLTF = TwoTextureOneUri(),
};
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
Assert.AreEqual(1, items.Length);
}
{
var parser = new GltfParser
{
GLTF = TwoTextureOneImage(),
};
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
Assert.AreEqual(1, items.Length);
}
{
var parser = new GltfParser
{
GLTF = CombineMetallicSmoothOcclusion(),
};
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
Assert.AreEqual(1, items.Length);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 544988eb7d07aca41b87d167dbc79c62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,6 @@
namespace VRMShaders
using System.IO;
namespace VRMShaders
{
public struct TextureImportName
{
@@ -6,14 +8,38 @@
public readonly string ConvertedName;
public readonly string Ext;
public string Uri;
public readonly string Uri;
public readonly string ExtractKey;
public TextureImportName(string gltfName, string convertedName, string ext, string uri)
public static string GetExtractKey(TextureImportTypes type, string gltfName, string convertedName, string uri)
{
if (type == TextureImportTypes.StandardMap)
{
// metallic, smooth, occlusion
return convertedName;
}
else
{
if (!string.IsNullOrEmpty(uri))
{
// external image
return Path.GetFileNameWithoutExtension(uri);
}
else
{
// texture name
return gltfName;
}
}
}
public TextureImportName(TextureImportTypes textureType, string gltfName, string ext, string uri)
{
GltfName = gltfName;
ConvertedName = convertedName;
ConvertedName = TextureImportName.Convert(gltfName, textureType);
Ext = ext;
Uri = uri;
ExtractKey = GetExtractKey(textureType, gltfName, ConvertedName, uri);
}
public string GltfFileName => $"{GltfName}{Ext}";

View File

@@ -29,6 +29,9 @@ namespace VRMShaders
public string ConvertedName => Name.ConvertedName;
public string ConvertedFileName => Name.ConvertedFileName;
public string Uri => Name.Uri;
public string ExtractKey => Name.ExtractKey;
public Vector2 Offset;
public Vector2 Scale;