Merge pull request #1791 from Santarh/fixImageIndexIdentification

Fix a importing error when the model using KHR_texture_basisu extension.
This commit is contained in:
ousttrue 2022-09-13 14:35:15 +09:00 committed by GitHub
commit 13011e1144
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 55 deletions

View File

@ -12,6 +12,8 @@ namespace UniGLTF
/// </summary>
public static class GltfTextureImporter
{
public static bool ImportKhrTextureBasisuExtension { get; set; } = true;
/// <summary>
/// glTF の Texture が存在せず Image のみのものを、Texture として扱いたい場合の関数.
/// </summary>
@ -38,14 +40,15 @@ namespace UniGLTF
public static bool TryCreateSrgb(GltfData data, int textureIndex, Vector2 offset, Vector2 scale, out SubAssetKey key, out TextureDescriptor desc)
{
var gltfTexture = data.GLTF.textures[textureIndex];
if (!gltfTexture.source.HasValidIndex())
var imageIndex = GetImageIndexFromTextureIndex(data, textureIndex);
if (!imageIndex.HasValue)
{
key = default;
desc = default;
return false;
}
var gltfImage = data.GLTF.images[gltfTexture.source.Value];
var gltfImage = data.GLTF.images[imageIndex.Value];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfTexture.name, gltfImage.uri);
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
desc = new TextureDescriptor(
@ -55,7 +58,7 @@ namespace UniGLTF
TextureImportTypes.sRGB,
default,
default,
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
() => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex.Value)),
default, default, default, default, default);
key = desc.SubAssetKey;
return true;
@ -64,14 +67,15 @@ namespace UniGLTF
public static bool TryCreateLinear(GltfData data, int textureIndex, Vector2 offset, Vector2 scale, out SubAssetKey key, out TextureDescriptor desc)
{
var gltfTexture = data.GLTF.textures[textureIndex];
if (!gltfTexture.source.HasValidIndex())
var imageIndex = GetImageIndexFromTextureIndex(data, textureIndex);
if (!imageIndex.HasValue)
{
key = default;
desc = default;
return false;
}
var gltfImage = data.GLTF.images[gltfTexture.source.Value];
var gltfImage = data.GLTF.images[imageIndex.Value];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.Linear, gltfTexture.name, gltfImage.uri);
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
desc = new TextureDescriptor(
@ -82,7 +86,7 @@ namespace UniGLTF
TextureImportTypes.Linear,
default,
default,
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
() => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex.Value)),
default, default, default, default, default);
key = desc.SubAssetKey;
return true;
@ -91,14 +95,15 @@ namespace UniGLTF
public static bool TryCreateNormal(GltfData data, int textureIndex, Vector2 offset, Vector2 scale, out SubAssetKey key, out TextureDescriptor desc)
{
var gltfTexture = data.GLTF.textures[textureIndex];
if (!gltfTexture.source.HasValidIndex())
var imageIndex = GetImageIndexFromTextureIndex(data, textureIndex);
if (!imageIndex.HasValue)
{
key = default;
desc = default;
return false;
}
var gltfImage = data.GLTF.images[gltfTexture.source.Value];
var gltfImage = data.GLTF.images[imageIndex.Value];
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.NormalMap, gltfTexture.name, gltfImage.uri);
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
desc = new TextureDescriptor(
@ -109,7 +114,7 @@ namespace UniGLTF
TextureImportTypes.NormalMap,
default,
default,
() => Task.FromResult(GetImageBytesFromTextureIndex(data, textureIndex)),
() => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex.Value)),
default, default, default, default, default);
key = desc.SubAssetKey;
return true;
@ -118,35 +123,45 @@ namespace UniGLTF
public static bool TryCreateStandard(GltfData data, int? metallicRoughnessTextureIndex, int? occlusionTextureIndex, Vector2 offset, Vector2 scale, float metallicFactor, float roughnessFactor, out SubAssetKey key, out TextureDescriptor desc)
{
string name = default;
SamplerParam? sampler = default;
GetTextureBytesAsync getMetallicRoughnessAsync = default;
SamplerParam sampler = default;
GetTextureBytesAsync getOcclusionAsync = default;
if (metallicRoughnessTextureIndex.HasValue)
{
var gltfTexture = data.GLTF.textures[metallicRoughnessTextureIndex.Value];
if (gltfTexture.source.HasValidIndex())
var imageIndex = GetImageIndexFromTextureIndex(data, metallicRoughnessTextureIndex.Value);
if (imageIndex.HasValue)
{
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source.Value].uri);
var gltfImage = data.GLTF.images[imageIndex.Value];
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, gltfImage.uri);
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, metallicRoughnessTextureIndex.Value);
getMetallicRoughnessAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, metallicRoughnessTextureIndex.Value));
getMetallicRoughnessAsync = () => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex.Value));
}
}
GetTextureBytesAsync getOcclusionAsync = default;
if (occlusionTextureIndex.HasValue)
{
var gltfTexture = data.GLTF.textures[occlusionTextureIndex.Value];
if (gltfTexture.source.HasValidIndex())
var imageIndex = GetImageIndexFromTextureIndex(data, occlusionTextureIndex.Value);
if (imageIndex.HasValue)
{
var gltfImage = data.GLTF.images[imageIndex.Value];
if (string.IsNullOrEmpty(name))
{
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source.Value].uri);
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, gltfImage.uri);
}
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, occlusionTextureIndex.Value);
getOcclusionAsync = () => Task.FromResult(GetImageBytesFromTextureIndex(data, occlusionTextureIndex.Value));
sampler ??= TextureSamplerUtil.CreateSampler(data.GLTF, occlusionTextureIndex.Value);
getOcclusionAsync = () => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex.Value));
}
}
if (getMetallicRoughnessAsync == null && getOcclusionAsync == null)
{
key = default;
desc = default;
return false;
}
if (string.IsNullOrEmpty(name))
{
key = default;
@ -158,7 +173,7 @@ namespace UniGLTF
name,
offset,
scale,
sampler,
sampler.Value,
TextureImportTypes.StandardMap,
metallicFactor,
roughnessFactor,
@ -166,11 +181,6 @@ namespace UniGLTF
getOcclusionAsync,
default, default, default, default);
key = desc.SubAssetKey;
if (string.IsNullOrEmpty(desc.UnityObjectName))
{
throw new ArgumentNullException();
}
Debug.Log("${name}");
return true;
}
@ -206,43 +216,47 @@ namespace UniGLTF
return (offset, scale);
}
public static (byte[] binary, string mimeType)? GetImageBytesFromTextureIndex(GltfData data, int textureIndex)
private static (byte[] binary, string mimeType)? GetImageBytesFromImageIndex(GltfData data, int imageIndex)
{
if (Application.isPlaying)
if (imageIndex >= 0 && imageIndex < data.GLTF.images.Count)
{
// NOTE: Runtime の場合は、拡張を考える.
var imageIndex = GetImageIndexFromTexture(data, textureIndex);
if (textureIndex >= 0 && textureIndex < data.GLTF.textures.Count)
var imageBytes = data.GetBytesFromImage(imageIndex);
if (imageBytes.HasValue)
{
var texture = data.GLTF.textures[textureIndex];
if (glTF_KHR_texture_basisu.TryGet(texture, out var basisuExtension))
return (ToArray(imageBytes.Value.binary), imageBytes.Value.mimeType);
}
}
return default;
}
private static int? GetImageIndexFromTextureIndex(GltfData data, int textureIndex)
{
if (textureIndex >= 0 && textureIndex < data.GLTF.textures.Count)
{
var texture = data.GLTF.textures[textureIndex];
// NOTE: Runtime の場合は KHR_texture_basisu 拡張を考える.
if (ImportKhrTextureBasisuExtension &&
Application.isPlaying &&
glTF_KHR_texture_basisu.TryGet(texture, out var basisuExtension))
{
var basisuImageIndex = basisuExtension.source;
if (basisuImageIndex >= 0 && basisuImageIndex < data.GLTF.images.Count)
{
imageIndex = basisuExtension.source;
return basisuImageIndex;
}
}
if (!imageIndex.HasValue) return default;
var imageBytes = data.GetBytesFromImage(imageIndex.Value);
return (ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType);
var imageIndex = texture.source;
if (imageIndex >= 0 && imageIndex < data.GLTF.images.Count)
{
return imageIndex;
}
}
else
{
// NOTE: Editor の場合は通常通り読み込む.
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)
{
if (textureIndex < 0 || textureIndex >= data.GLTF.textures.Count) return default;
return data.GLTF.textures[textureIndex].source;
return default;
}
private static byte[] ToArray(NativeArray<byte> bytes)

View File

@ -54,7 +54,7 @@ namespace VRMShaders
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException("name");
throw new ArgumentNullException(nameof(name));
}
UnityObjectName = name;
Offset = offset;

View File

@ -416,9 +416,10 @@ namespace VRM.SimpleViewer
case ".glb":
case ".zip":
{
var instance = await GltfUtility.LoadBytesAsync(path, bytes,
var instance = await GltfUtility.LoadAsync(path,
GetIAwaitCaller(m_useAsync.isOn),
GetGltfMaterialGenerator(m_useUrpMaterial.isOn));
SetModel(instance);
break;
}