mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-14 14:59:43 -05:00
TextureImportParam.ExtractKey
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
242
Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs
Normal file
242
Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs.meta
Normal file
11
Assets/UniGLTF/Tests/UniGLTF/TextureEnumerateTests.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 544988eb7d07aca41b87d167dbc79c62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}";
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user