GetBytesWithMime を VRMShaders に移動

* UniGLTF.GltfTextureExporter.GetBytesWithMime を VRMShaders.AssetTextureUtil.GetTextureBytesWithMime に移動
* テスト NotReadable, Compressed を VRMShaders に移動
* テスト用リソース Resources/4x4.png と 4x4compressed.DDS を VRMShaders に移動
This commit is contained in:
ousttrue
2021-04-12 18:05:21 +09:00
parent 14e5683ed2
commit e35bc5f2fe
32 changed files with 154 additions and 255 deletions

View File

@@ -36,10 +36,9 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf, inverseAxis))
{
exporter.Prepare(go);
exporter.Export(settings, AssetTextureUtil.IsTextureEditorAsset);
exporter.Export(settings, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
}
if (isGlb)
{
var bytes = gltf.ToGlbBytes();

View File

@@ -6,64 +6,6 @@ namespace UniGLTF
{
public static class GltfTextureExporter
{
/// <summary>
/// 画像のバイト列を得る
/// </summary>
/// <param name="bytes"></param>
/// <param name="texture"></param>
/// <returns></returns>
public static (byte[] bytes, string mine) GetBytesWithMime(Texture2D texture)
{
#if UNITY_EDITOR
var path = UnityPath.FromAsset(texture);
if (path.IsUnderAssetsFolder)
{
if (path.Extension == ".png")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/png"
);
}
if (path.Extension == ".jpg")
{
return
(
System.IO.File.ReadAllBytes(path.FullPath),
"image/jpeg"
);
}
}
#endif
try
{
var png = texture.EncodeToPNG();
if (png != null)
{
return (png, "image/png");
}
}
catch (Exception ex)
{
// fail to EncodeToPng
// System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.
Debug.LogWarning(ex);
}
{
// try copy and EncodeToPng
var copy = TextureConverter.CopyTexture(texture, TextureImportTypes.sRGB, null);
var png = copy.EncodeToPNG();
UnityEngine.Object.DestroyImmediate(copy);
return (png, "image/png");
}
}
/// <summary>
/// gltf に texture を足す
///
@@ -79,9 +21,9 @@ namespace UniGLTF
/// <param name="bufferIndex"></param>
/// <param name="texture"></param>
/// <returns>gltf texture index</returns>
public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture)
public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, Func<Texture2D, (byte[] bytes, string mime)> getTextureBytes)
{
var bytesWithMime = GetBytesWithMime(texture);
var bytesWithMime = getTextureBytes(texture);
// add view
var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE);
@@ -93,7 +35,7 @@ namespace UniGLTF
{
name = TextureImportName.RemoveSuffix(texture.name),
bufferView = viewIndex,
mimeType = bytesWithMime.mine,
mimeType = bytesWithMime.mime,
});
// add sampler

View File

@@ -164,12 +164,12 @@ namespace UniGLTF
return node;
}
public virtual void ExportExtensions()
public virtual void ExportExtensions(Func<Texture2D, (byte[], string)> getTextureBytes)
{
}
public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture, bool> useAsset)
public virtual void Export(MeshExportSettings meshExportSettings, Func<Texture, bool> useAsset, Func<Texture2D, (byte[], string)> getTextureBytes)
{
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
var bufferIndex = glTF.AddBuffer(bytesBuffer);
@@ -302,13 +302,13 @@ namespace UniGLTF
#endregion
#endif
ExportExtensions();
ExportExtensions(getTextureBytes);
// Extension で Texture が増える場合があるので最後に呼ぶ
for (int i = 0; i < TextureManager.Exported.Count; ++i)
{
var unityTexture = TextureManager.Exported[i];
glTF.PushGltfTexture(bufferIndex, unityTexture);
glTF.PushGltfTexture(bufferIndex, unityTexture, getTextureBytes);
}
}
#endregion

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ee977e7fc2164bd408c27953f01dd8f1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,88 +0,0 @@
fileFormatVersion: 2
guid: db15802c623d98042a8cf5f03959818c
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -61,7 +61,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(root);
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset);
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
return gltf.ToGlbBytes();
}
}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3ff3cfe62633ecc40a4ee5b12d3e680f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 560 B

View File

@@ -15,7 +15,7 @@ namespace UniGLTF
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Trilinear,
};
var textureManager = new TextureExporter(AssetTextureUtil.IsTextureEditorAsset );
var textureManager = new TextureExporter(AssetTextureUtil.IsTextureEditorAsset);
var material = new Material(Shader.Find("Standard"));
material.mainTexture = tex0;
@@ -31,24 +31,5 @@ namespace UniGLTF
Assert.AreEqual(glFilter.LINEAR_MIPMAP_LINEAR, sampler.minFilter);
Assert.AreEqual(glFilter.LINEAR_MIPMAP_LINEAR, sampler.magFilter);
}
[Test]
public void NotReadable()
{
var readonlyTexture = Resources.Load<Texture2D>("4x4");
Assert.False(readonlyTexture.isReadable);
var (bytes, mime) = GltfTextureExporter.GetBytesWithMime(readonlyTexture);
Assert.NotNull(bytes);
}
[Test]
public void Compressed()
{
var readonlyTexture = Resources.Load<Texture2D>("4x4compressed");
Assert.False(readonlyTexture.isReadable);
var (bytes, mime) = GltfTextureExporter.GetBytesWithMime(readonlyTexture);
Assert.NotNull(bytes);
}
}
}

View File

@@ -106,7 +106,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset );
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
// remove empty buffer
gltf.buffers.Clear();
@@ -298,7 +298,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(CreateSimpleScene());
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset );
exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
}
var expected = gltf.ToJson().ParseAsJson();
@@ -534,7 +534,7 @@ namespace UniGLTF
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(UniGLTF.MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset );
exporter.Export(UniGLTF.MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
json = gltf.ToJson();
}

View File

@@ -170,7 +170,7 @@ namespace VRM.Samples
*/
importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root, AssetTextureUtil.IsTextureEditorAsset );
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
// TODO: Check contents in JSON
/*var exportJson = */

View File

@@ -3,6 +3,7 @@ using UniGLTF;
using UnityEngine;
using UnityEngine.UI;
using VRM;
using VRMShaders;
namespace VRM.Samples
{
@@ -95,7 +96,7 @@ namespace VRM.Samples
return;
}
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, m_model, _ => false);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, m_model, (Texture _) => false, TextureExporter.GetTextureBytesWithMime);
var bytes = vrm.ToGlbBytes();
File.WriteAllBytes(path, bytes);
Debug.LogFormat("export to {0}", path);

View File

@@ -6,13 +6,12 @@
"UniGLTF",
"VRMShaders.GLTF.IO.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
"defineConstraints": []
}

View File

@@ -225,7 +225,7 @@ namespace VRM
using (var exporter = new VRMExporter(gltf))
{
exporter.Prepare(target);
exporter.Export(settings.MeshExportSettings, AssetTextureUtil.IsTextureEditorAsset );
exporter.Export(settings.MeshExportSettings, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
}
var bytes = gltf.ToGlbBytes();
File.WriteAllBytes(path, bytes);

View File

@@ -14,13 +14,13 @@ namespace VRM
return new VRMMaterialExporter();
}
public static glTF Export(MeshExportSettings configuration, GameObject go, Func<Texture, bool> useAsset)
public static glTF Export(MeshExportSettings configuration, GameObject go, Func<Texture, bool> useAsset, Func<Texture2D, (byte[], string)> getTextureBytes)
{
var gltf = new glTF();
using (var exporter = new VRMExporter(gltf))
{
exporter.Prepare(go);
exporter.Export(configuration, useAsset);
exporter.Export(configuration, useAsset, getTextureBytes);
}
return gltf;
}
@@ -32,7 +32,7 @@ namespace VRM
gltf.extensionsUsed.Add(glTF_VRM_extensions.ExtensionName);
}
public override void ExportExtensions()
public override void ExportExtensions(Func<Texture2D, (byte[], string)> getTextureBytes)
{
// avatar
var animator = Copy.GetComponent<Animator>();
@@ -110,7 +110,7 @@ namespace VRM
VRM.meta.title = meta.Title;
if (meta.Thumbnail != null)
{
VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail);
VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, getTextureBytes);
}
VRM.meta.licenseType = meta.LicenseType;

View File

@@ -106,7 +106,7 @@ namespace VRM
try
{
// export
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, go, AssetTextureUtil.IsTextureEditorAsset );
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, go, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
// re import
if (vrm != null)

View File

@@ -320,7 +320,7 @@ namespace UniVRM10
// export vrm-1.0
var exporter = new UniVRM10.Vrm10Exporter(AssetTextureUtil.IsTextureEditorAsset);
var option = new VrmLib.ExportArgs();
exporter.Export(root, model, converter, option, Meta ? Meta : m_tmpMeta);
exporter.Export(root, model, converter, option, AssetTextureUtil.GetTextureBytesWithMime, Meta ? Meta : m_tmpMeta);
var exportedBytes = exporter.Storage.ToBytes();

View File

@@ -1,10 +1,12 @@
using VrmLib;
using System;
using UnityEngine;
namespace UniVRM10
{
public static class ModelExtensions
{
public static byte[] ToGlb(this VrmLib.Model model)
public static byte[] ToGlb(this VrmLib.Model model, Func<Texture2D, (byte[], string)> getTextureBytes)
{
// export vrm-1.0
var exporter10 = new Vrm10Exporter(_ => false);
@@ -12,7 +14,7 @@ namespace UniVRM10
{
// vrm = false
};
exporter10.Export(null, model, null, option);
exporter10.Export(null, model, null, option, getTextureBytes);
var glb10 = UniGLTF.Glb.Parse(exporter10.Storage.ToBytes());
return glb10.ToBytes();
}

View File

@@ -128,7 +128,7 @@ namespace UniVRM10
return new float[] { -v.x, v.y, v.z };
}
public void Export(GameObject root, Model model, RuntimeVrmConverter converter, ExportArgs option, VRM10MetaObject metaObject = null)
public void Export(GameObject root, Model model, RuntimeVrmConverter converter, ExportArgs option, Func<Texture2D, (byte[], string)> getTextureBytes, VRM10MetaObject metaObject = null)
{
ExportAsset(model);
@@ -182,7 +182,7 @@ namespace UniVRM10
for (int i = 0; i < m_textureExporter.Exported.Count; ++i)
{
var unityTexture = m_textureExporter.Exported[i];
Storage.Gltf.PushGltfTexture(0, unityTexture);
Storage.Gltf.PushGltfTexture(0, unityTexture, getTextureBytes);
}
if (thumbnailTextureIndex.HasValue)

View File

@@ -1,35 +0,0 @@
using UniVRM10;
using VrmLib;
public static class ExportDebugUtil
{
public static void SaveJson(VrmLib.Model model, string path)
{
using (var stream = new System.IO.StreamWriter(path))
{
stream.Write(GetJsonString(model));
}
}
public static void SaveVrm(VrmLib.Model model, string path)
{
using (var stream = new System.IO.StreamWriter(path))
{
stream.Write(model.ToGlb());
}
}
public static string GetJsonString(VrmLib.Model model)
{
// export vrm-1.0
var exporter10 = new Vrm10Exporter(_ => false);
var option = new VrmLib.ExportArgs
{
// vrm = false
};
exporter10.Export(null, model, null, option);
var glbBytes10 = exporter10.Storage.ToBytes();
var glb10 = UniGLTF.Glb.Parse(glbBytes10);
return System.Text.Encoding.UTF8.GetString(glb10.Json.Bytes.Array, glb10.Json.Bytes.Offset, glb10.Json.Bytes.Count);
}
}

View File

@@ -4,6 +4,7 @@ using UnityEngine;
using VrmLib;
using UniVRM10;
using UniGLTF;
using VRMShaders;
public class Sample : MonoBehaviour
{
@@ -34,7 +35,7 @@ public class Sample : MonoBehaviour
var model = exporter.ToModelFrom10(vrm0x);
// 右手系に変換
model.ConvertCoordinate(VrmLib.Coordinates.Vrm1);
var exportedBytes = model.ToGlb();
var exportedBytes = model.ToGlb(TextureExporter.GetTextureBytesWithMime);
// Import 1.0
var vrm10 = Import(exportedBytes, src);

View File

@@ -4,6 +4,7 @@ using NUnit.Framework;
using UniGLTF;
using UnityEngine;
using UnityEngine.TestTools;
using VRMShaders;
namespace UniVRM10.Test
{
@@ -45,7 +46,7 @@ namespace UniVRM10.Test
{
// 右手系に変換
VrmLib.ModelExtensionsForCoordinates.ConvertCoordinate(model, VrmLib.Coordinates.Vrm1);
var bytes = UniVRM10.ModelExtensions.ToGlb(model);
var bytes = UniVRM10.ModelExtensions.ToGlb(model, AssetTextureUtil.GetTextureBytesWithMime);
return bytes;
}

View File

@@ -3,7 +3,8 @@
"references": [
"VrmLib",
"VRM10",
"UniGLTF"
"UniGLTF",
"VRMShaders.GLTF.IO.Editor"
],
"optionalUnityReferences": [
"TestAssemblies"

View File

@@ -1,3 +1,4 @@
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
@@ -67,5 +68,53 @@ namespace VRMShaders
// not Texture2D or not exists Texture2D asset. EncodeToPng
return false;
}
/// <summary>
/// Assetから画像のバイト列を得る
/// </summary>
/// <param name="bytes"></param>
/// <param name="texture"></param>
/// <returns></returns>
public static bool TryGetBytesWithMime(Texture2D texture, out byte[] bytes, out string mime)
{
var path = AssetDatabase.GetAssetOrScenePath(texture);
if (string.IsNullOrEmpty(path))
{
bytes = default;
mime = default;
return false;
}
var ext = Path.GetExtension(path).ToLower();
switch (ext)
{
case ".png":
bytes = System.IO.File.ReadAllBytes(path);
mime = "image/png";
return true;
case ".jpg":
bytes = System.IO.File.ReadAllBytes(path);
mime = "image/jpeg";
return true;
}
// dds ? astc ? tga ?
bytes = default;
mime = default;
return false;
}
public static (byte[], string) GetTextureBytesWithMime(Texture2D texture)
{
if (TryGetBytesWithMime(texture, out byte[] bytes, out string mime))
{
return (bytes, mime);
}
return TextureExporter.GetTextureBytesWithMime(texture);
}
}
}

View File

@@ -1,6 +1,9 @@
{
"name": "VRMShaders.GLTF.IO.Editor",
"references": [],
"references": [
"VRMShaders.GLTF.IO.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
@@ -9,7 +12,5 @@
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
"defineConstraints": []
}

View File

@@ -196,5 +196,37 @@ namespace VRMShaders
return index;
}
/// <summary>
/// 画像のバイト列を得る
/// </summary>
/// <param name="bytes"></param>
/// <param name="texture"></param>
/// <returns></returns>
public static (byte[] bytes, string mime) GetTextureBytesWithMime(Texture2D texture)
{
try
{
var png = texture.EncodeToPNG();
if (png != null)
{
return (png, "image/png");
}
}
catch (Exception ex)
{
// fail to EncodeToPng
// System.ArgumentException: not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.
Debug.LogWarning(ex);
}
{
// try copy and EncodeToPng
var copy = TextureConverter.CopyTexture(texture, TextureImportTypes.sRGB, null);
var png = copy.EncodeToPNG();
UnityEngine.Object.DestroyImmediate(copy);
return (png, "image/png");
}
}
}
}

View File

Before

Width:  |  Height:  |  Size: 560 B

After

Width:  |  Height:  |  Size: 560 B

View File

@@ -0,0 +1,29 @@
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
namespace VRMShaders
{
public class TextureBytesTests
{
static string AssetPath = "Assets/VRMShaders/GLTF/IO/Tests";
[Test]
public void NotReadable()
{
var readonlyTexture = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4.png");
Assert.False(readonlyTexture.isReadable);
var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(readonlyTexture);
Assert.NotNull(bytes);
}
[Test]
public void Compressed()
{
var readonlyTexture = AssetDatabase.LoadAssetAtPath<Texture2D>($"{AssetPath}/4x4compressed.dds");
Assert.False(readonlyTexture.isReadable);
var (bytes, mime) = AssetTextureUtil.GetTextureBytesWithMime(readonlyTexture);
Assert.NotNull(bytes);
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cee5c63e6473ed848a935b446d60cccf
guid: 2c9ac46bc2fc4d947bab6555f14d1d9f
MonoImporter:
externalObjects: {}
serializedVersion: 2