mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-06 17:54:14 -05:00
Texture読み込みをなるべくNativeArrayによせる
This commit is contained in:
parent
dcf20ab3c6
commit
f0a79d1a34
|
|
@ -1,4 +1,5 @@
|
|||
using UnityEngine;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
|
|
@ -8,9 +9,11 @@ namespace UniGLTF
|
|||
public sealed class DeserializingTextureInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Texture のバイト列
|
||||
/// Texture のバイト列。
|
||||
/// GltfData が保持する NativeArray をコピーせずそのまま参照するため、Dispose してはならない。
|
||||
/// 未設定の場合は IsCreated == false となる。
|
||||
/// </summary>
|
||||
public byte[] ImageData { get; }
|
||||
public NativeArray<byte> ImageData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Texture の mimeType
|
||||
|
|
@ -44,7 +47,7 @@ namespace UniGLTF
|
|||
|
||||
public TextureImportTypes ImportTypes { get; }
|
||||
|
||||
public DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV)
|
||||
public DeserializingTextureInfo(NativeArray<byte> imageData, string dataMimeType, ColorSpace colorSpace, bool useMipmap, FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV)
|
||||
{
|
||||
ImageData = imageData;
|
||||
DataMimeType = dataMimeType;
|
||||
|
|
@ -55,7 +58,7 @@ namespace UniGLTF
|
|||
WrapModeV = wrapModeV;
|
||||
}
|
||||
|
||||
public DeserializingTextureInfo(byte[] imageData, string dataMimeType, ColorSpace colorSpace, SamplerParam samplerParam, TextureImportTypes importTypes)
|
||||
public DeserializingTextureInfo(NativeArray<byte> imageData, string dataMimeType, ColorSpace colorSpace, SamplerParam samplerParam, TextureImportTypes importTypes)
|
||||
{
|
||||
ImageData = imageData;
|
||||
DataMimeType = dataMimeType;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,7 @@ namespace UniGLTF
|
|||
TextureImportTypes.sRGB,
|
||||
default,
|
||||
default,
|
||||
() =>
|
||||
{
|
||||
var imageBytes = data.GetBytesFromImage(imageIndex);
|
||||
return Task.FromResult<(byte[], string)?>((ToArray(imageBytes?.binary ?? default), imageBytes?.mimeType));
|
||||
},
|
||||
() => Task.FromResult(GetImageBytesFromImageIndex(data, imageIndex)),
|
||||
default, default, default, default, default);
|
||||
return (texDesc.SubAssetKey, texDesc);
|
||||
}
|
||||
|
|
@ -214,19 +210,10 @@ namespace UniGLTF
|
|||
return (offset, scale);
|
||||
}
|
||||
|
||||
private static (byte[] binary, string mimeType)? GetImageBytesFromImageIndex(GltfData data, int imageIndex)
|
||||
private static (NativeArray<byte> binary, string mimeType)? GetImageBytesFromImageIndex(GltfData data, int imageIndex)
|
||||
{
|
||||
if (imageIndex >= 0 && imageIndex < data.GLTF.images.Count)
|
||||
{
|
||||
var imageBytes = data.GetBytesFromImage(imageIndex);
|
||||
if (imageBytes.HasValue)
|
||||
{
|
||||
|
||||
return (ToArray(imageBytes.Value.binary), imageBytes.Value.mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
// NOTE: GltfData が保持する NativeArray をコピーせずそのまま返す。
|
||||
return data.GetBytesFromImage(imageIndex);
|
||||
}
|
||||
|
||||
private static int? GetImageIndexFromTextureIndex(GltfData data, int textureIndex)
|
||||
|
|
@ -272,25 +259,5 @@ namespace UniGLTF
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static byte[] ToArray(NativeArray<byte> 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;
|
||||
// }
|
||||
return bytes.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,16 @@ namespace UniGLTF
|
|||
#pragma warning restore 1998
|
||||
{
|
||||
#if USE_COM_UNITY_CLOUD_KTX
|
||||
if (textureInfo.ImageData == null) return null;
|
||||
if (!textureInfo.ImageData.IsCreated) return null;
|
||||
|
||||
// NOTE: IAwaitCaller を無視するので、同期読み込みを期待する環境で同期読み込みができない
|
||||
try
|
||||
{
|
||||
var ktxTexture = new KtxTexture();
|
||||
using var nativeBytes = new NativeArray<byte>(textureInfo.ImageData, Allocator.Persistent);
|
||||
// NOTE: GltfData が保持する NativeArray をそのまま渡す。
|
||||
// KtxUnity は Open() 内で同期的に読み取るだけで所有権を取らないため、コピー不要。
|
||||
var result = await ktxTexture.LoadFromBytes(
|
||||
nativeBytes,
|
||||
textureInfo.ImageData,
|
||||
linear: textureInfo.ColorSpace == ColorSpace.Linear,
|
||||
mipChain: textureInfo.UseMipmap
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -11,9 +12,12 @@ namespace UniGLTF
|
|||
/// Texture2D.LoadImage
|
||||
/// extact:
|
||||
/// File.WriteAllBytes
|
||||
///
|
||||
/// NOTE: binary は GltfData が保持する NativeArray をそのまま参照する。
|
||||
/// コピーを避けるため、呼び出し側で Dispose してはならない。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public delegate Task<(byte[] binary, string mimeType)?> GetTextureBytesAsync();
|
||||
public delegate Task<(NativeArray<byte> binary, string mimeType)?> GetTextureBytesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 入力 glTF ファイルを Import した結果生成される、UnityEngine.Texture のアセット 1 つを確定させる Import 情報。
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace UniGLTF
|
|||
// https://docs.unity3d.com/2018.4/Documentation/Manual/StandardShaderMaterialParameterNormalMap.html
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
new DeserializingTextureInfo(data0?.binary ?? default, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
|
|
@ -100,14 +100,14 @@ namespace UniGLTF
|
|||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
metallicRoughnessTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
new DeserializingTextureInfo(data0?.binary ?? default, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
awaitCaller);
|
||||
}
|
||||
if (texDesc.Index1 != null)
|
||||
{
|
||||
var data1 = await texDesc.Index1();
|
||||
occlusionTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data1?.binary, data1?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
new DeserializingTextureInfo(data1?.binary ?? default, data1?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
awaitCaller);
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ namespace UniGLTF
|
|||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.sRGB, texDesc.Sampler, texDesc.TextureType),
|
||||
new DeserializingTextureInfo(data0?.binary ?? default, data0?.mimeType, ColorSpace.sRGB, texDesc.Sampler, texDesc.TextureType),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
|
|
@ -137,7 +137,7 @@ namespace UniGLTF
|
|||
{
|
||||
var data0 = await texDesc.Index0();
|
||||
var rawTexture = await TextureDeserializer.LoadTextureAsync(
|
||||
new DeserializingTextureInfo(data0?.binary, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
new DeserializingTextureInfo(data0?.binary ?? default, data0?.mimeType, ColorSpace.Linear, texDesc.Sampler, texDesc.TextureType),
|
||||
awaitCaller);
|
||||
rawTexture.name = subAssetKey.Name;
|
||||
_textureCache.Add(subAssetKey, rawTexture);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -29,12 +30,17 @@ namespace UniGLTF
|
|||
|
||||
public async Task<Texture2D> LoadTextureAsync(DeserializingTextureInfo textureInfo, IAwaitCaller awaitCaller)
|
||||
{
|
||||
if (textureInfo.ImageData == null) return null;
|
||||
if (!textureInfo.ImageData.IsCreated) return null;
|
||||
|
||||
try
|
||||
{
|
||||
var texture = new Texture2D(2, 2, TextureFormat.ARGB32, textureInfo.UseMipmap, textureInfo.ColorSpace == ColorSpace.Linear);
|
||||
texture.LoadImage(textureInfo.ImageData, ImportedTexturesAccessibility.ToMarkNonReadable());
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
// Unity 6000.0.42f1 以降は LoadImage が ReadOnlySpan を受け取れるため、NativeArray からのコピーを避ける。
|
||||
texture.LoadImage(textureInfo.ImageData.AsReadOnlySpan(), ImportedTexturesAccessibility.ToMarkNonReadable());
|
||||
#else
|
||||
texture.LoadImage(textureInfo.ImageData.ToArray(), ImportedTexturesAccessibility.ToMarkNonReadable());
|
||||
#endif
|
||||
await awaitCaller.NextFrame();
|
||||
|
||||
texture.wrapModeU = textureInfo.WrapModeU;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user