mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-14 06:50:19 -05:00
Merge pull request #837 from ousttrue/feature10/update_vrm1_loader
vrm1のローダー更新
This commit is contained in:
@@ -34,14 +34,14 @@ namespace UniGLTF
|
||||
static bool s_foldMaterials = true;
|
||||
static bool s_foldTextures = true;
|
||||
|
||||
public static void OnGUIMaterial(ScriptedImporter importer, GltfParser parser)
|
||||
public static void OnGUIMaterial(ScriptedImporter importer, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures)
|
||||
{
|
||||
var canExtract = !importer.GetExternalObjectMap().Any(x => x.Value is Material || x.Value is Texture2D);
|
||||
using (new TmpGuiEnable(canExtract))
|
||||
{
|
||||
if (GUILayout.Button("Extract Materials And Textures ..."))
|
||||
{
|
||||
ExtractMaterialsAndTextures(importer, parser);
|
||||
ExtractMaterialsAndTextures(importer, parser, enumTextures);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace UniGLTF
|
||||
s_foldTextures = EditorGUILayout.Foldout(s_foldTextures, "Remapped Textures");
|
||||
if (s_foldTextures)
|
||||
{
|
||||
var names = GltfTextureEnumerator.Enumerate(parser)
|
||||
var names = enumTextures(parser)
|
||||
.Select(x =>
|
||||
{
|
||||
if (x.TextureType != TextureImportTypes.StandardMap && !string.IsNullOrEmpty(x.Uri))
|
||||
@@ -122,7 +122,7 @@ namespace UniGLTF
|
||||
AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser)
|
||||
static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures)
|
||||
{
|
||||
if (string.IsNullOrEmpty(self.assetPath))
|
||||
{
|
||||
@@ -143,7 +143,7 @@ namespace UniGLTF
|
||||
var assetPath = UnityPath.FromFullpath(parser.TargetPath);
|
||||
var dirName = $"{assetPath.FileNameWithoutExtension}.Textures";
|
||||
TextureExtractor.ExtractTextures(parser, assetPath.Parent.Child(dirName),
|
||||
GltfTextureEnumerator.Enumerate,
|
||||
enumTextures,
|
||||
self.GetSubAssets<UnityEngine.Texture2D>(self.assetPath).ToArray(),
|
||||
addRemap,
|
||||
onCompleted
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace UniGLTF
|
||||
break;
|
||||
|
||||
case Tabs.Materials:
|
||||
EditorMaterial.OnGUIMaterial(m_importer, m_parser);
|
||||
EditorMaterial.OnGUIMaterial(m_importer, m_parser, GltfTextureEnumerator.EnumerateAllTexturesDistinct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace UniGLTF
|
||||
break;
|
||||
|
||||
case Tabs.Materials:
|
||||
EditorMaterial.OnGUIMaterial(m_importer, m_parser);
|
||||
EditorMaterial.OnGUIMaterial(m_importer, m_parser, GltfTextureEnumerator.EnumerateAllTexturesDistinct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
@@ -37,32 +36,28 @@ namespace UniGLTF
|
||||
// Import(create unity objects)
|
||||
//
|
||||
var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray();
|
||||
|
||||
|
||||
var externalTextures = EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent).ToArray();
|
||||
|
||||
using (var loaded = new ImporterContext(parser, externalObjectMap.Concat(externalTextures)))
|
||||
using (var loader = new ImporterContext(parser, externalObjectMap.Concat(externalTextures)))
|
||||
{
|
||||
// settings TextureImporters
|
||||
foreach (var textureInfo in GltfTextureEnumerator.Enumerate(parser))
|
||||
foreach (var textureInfo in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
|
||||
{
|
||||
TextureImporterConfigurator.Configure(textureInfo, loaded.TextureFactory.ExternalMap);
|
||||
TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
|
||||
}
|
||||
|
||||
loaded.InvertAxis = reverseAxis;
|
||||
loaded.Load();
|
||||
loaded.ShowMeshes();
|
||||
loader.InvertAxis = reverseAxis;
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
|
||||
loaded.TransferOwnership(o =>
|
||||
loader.TransferOwnership(o =>
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
Debug.Log($"[{o.GetType().Name}] {o.name} will not destroy");
|
||||
#endif
|
||||
|
||||
context.AddObjectToAsset(o.name, o);
|
||||
if (o is GameObject)
|
||||
{
|
||||
// Root GameObject is main object
|
||||
context.SetMainObject(loaded.Root);
|
||||
context.SetMainObject(loader.Root);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -74,7 +69,7 @@ namespace UniGLTF
|
||||
GltfParser parser, UnityPath dir)
|
||||
{
|
||||
var used = new HashSet<Texture2D>();
|
||||
foreach (var texParam in GltfTextureEnumerator.Enumerate(parser))
|
||||
foreach (var texParam in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
|
||||
{
|
||||
switch (texParam.TextureType)
|
||||
{
|
||||
@@ -96,8 +91,10 @@ namespace UniGLTF
|
||||
{
|
||||
// exclude. skip
|
||||
}
|
||||
else{
|
||||
if(used.Add(asset)){
|
||||
else
|
||||
{
|
||||
if (used.Add(asset))
|
||||
{
|
||||
yield return (asset.name, asset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace UniGLTF
|
||||
/// <param name="dirName"></param>
|
||||
/// <param name="onCompleted"></param>
|
||||
public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
|
||||
TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action<Texture2D> addRemap,
|
||||
EnumerateAllTexturesDistinctFunc textureEnumerator, Texture2D[] subAssets, Action<Texture2D> addRemap,
|
||||
Action<IEnumerable<UnityPath>> onCompleted = null)
|
||||
{
|
||||
var extractor = new TextureExtractor(parser, textureDirectory, subAssets);
|
||||
|
||||
@@ -476,5 +476,51 @@ namespace UniGLTF
|
||||
self.RemoveUnusedExtensions(json);
|
||||
return (json, self.buffers);
|
||||
}
|
||||
|
||||
public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor)
|
||||
{
|
||||
if (string.IsNullOrEmpty(generatorVersion)) return false;
|
||||
if (generatorVersion == "UniGLTF") return true;
|
||||
if (!generatorVersion.FastStartsWith("UniGLTF-")) return false;
|
||||
|
||||
try
|
||||
{
|
||||
var splitted = generatorVersion.Substring(8).Split('.');
|
||||
var generatorMajor = int.Parse(splitted[0]);
|
||||
var generatorMinor = int.Parse(splitted[1]);
|
||||
|
||||
if (generatorMajor < major)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (generatorMajor > major)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (generatorMinor >= minor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsGeneratedUniGLTFAndOlder(this glTF gltf, int major, int minor)
|
||||
{
|
||||
if (gltf == null) return false;
|
||||
if (gltf.asset == null) return false;
|
||||
return IsGeneratedUniGLTFAndOlderThan(gltf.asset.generator, major, minor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
@@ -27,9 +26,11 @@ namespace UniGLTF
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ArraySegment<byte> GetBytes()
|
||||
public void ExtendCapacity(int capacity)
|
||||
{
|
||||
return m_bytes;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ArraySegment<byte> Bytes => m_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ namespace UniGLTF
|
||||
public interface IBytesBuffer
|
||||
{
|
||||
string Uri { get; }
|
||||
ArraySegment<Byte> GetBytes();
|
||||
glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct;
|
||||
ArraySegment<Byte> Bytes { get; }
|
||||
glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target = glBufferTarget.NONE) where T : struct;
|
||||
void ExtendCapacity(int capacity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ namespace UniGLTF
|
||||
[Serializable]
|
||||
public class glTFBuffer
|
||||
{
|
||||
IBytesBuffer Storage;
|
||||
IBytesBuffer m_buffer;
|
||||
public IBytesBuffer Buffer => m_buffer;
|
||||
|
||||
public void OpenStorage(IStorage storage)
|
||||
{
|
||||
Storage = new ArraySegmentByteBuffer(storage.Get(uri));
|
||||
m_buffer = new ArraySegmentByteBuffer(storage.Get(uri));
|
||||
}
|
||||
|
||||
public glTFBuffer()
|
||||
@@ -20,7 +21,7 @@ namespace UniGLTF
|
||||
|
||||
public glTFBuffer(IBytesBuffer storage)
|
||||
{
|
||||
Storage = storage;
|
||||
m_buffer = storage;
|
||||
}
|
||||
|
||||
public string uri;
|
||||
@@ -39,14 +40,14 @@ namespace UniGLTF
|
||||
}
|
||||
public glTFBufferView Append<T>(ArraySegment<T> segment, glBufferTarget target) where T : struct
|
||||
{
|
||||
var view = Storage.Extend(segment, target);
|
||||
byteLength = Storage.GetBytes().Count;
|
||||
var view = m_buffer.Extend(segment, target);
|
||||
byteLength = m_buffer.Bytes.Count;
|
||||
return view;
|
||||
}
|
||||
|
||||
public ArraySegment<Byte> GetBytes()
|
||||
{
|
||||
return Storage.GetBytes();
|
||||
return m_buffer.Bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
98
Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs
Normal file
98
Assets/UniGLTF/Runtime/UniGLTF/IO/ArrayByteBuffer.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// for exporter
|
||||
/// </summary>
|
||||
public class ArrayByteBuffer : IBytesBuffer
|
||||
{
|
||||
public string Uri
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
Byte[] m_bytes;
|
||||
int m_used;
|
||||
|
||||
public ArrayByteBuffer(Byte[] bytes = null)
|
||||
{
|
||||
Uri = "";
|
||||
m_bytes = bytes;
|
||||
}
|
||||
|
||||
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
|
||||
{
|
||||
using (var pin = Pin.Create(array))
|
||||
{
|
||||
var elementSize = Marshal.SizeOf(typeof(T));
|
||||
var view = Extend(pin.Ptr, array.Count * elementSize, elementSize, target);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
public glTFBufferView Extend(IntPtr p, int bytesLength, int stride, glBufferTarget target)
|
||||
{
|
||||
var tmp = m_bytes;
|
||||
// alignment
|
||||
var padding = m_used % stride == 0 ? 0 : stride - m_used % stride;
|
||||
|
||||
if (m_bytes == null || m_used + padding + bytesLength > m_bytes.Length)
|
||||
{
|
||||
// recreate buffer
|
||||
m_bytes = new Byte[m_used + padding + bytesLength];
|
||||
if (m_used > 0)
|
||||
{
|
||||
Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
if (m_used + padding + bytesLength > m_bytes.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
Marshal.Copy(p, m_bytes, m_used + padding, bytesLength);
|
||||
var result = new glTFBufferView
|
||||
{
|
||||
buffer = 0,
|
||||
byteLength = bytesLength,
|
||||
byteOffset = m_used + padding,
|
||||
byteStride = stride,
|
||||
target = target,
|
||||
};
|
||||
m_used = m_used + padding + bytesLength;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ExtendCapacity(int capacity)
|
||||
{
|
||||
if (m_bytes != null && capacity < m_bytes.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newBuffer = new byte[capacity];
|
||||
if (m_bytes != null && m_used > 0)
|
||||
{
|
||||
Buffer.BlockCopy(m_bytes, 0, newBuffer, 0, m_used);
|
||||
}
|
||||
m_bytes = newBuffer;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> Bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_bytes == null)
|
||||
{
|
||||
return new ArraySegment<byte>();
|
||||
}
|
||||
|
||||
return new ArraySegment<byte>(m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9b840dcce2a5b94aae00d4bc4bf7e10
|
||||
guid: d095d4c4eb5e68f4bb10c21bb3604cdb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,158 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public static class IBytesBufferExtensions
|
||||
{
|
||||
public static glTFBufferView Extend<T>(this IBytesBuffer buffer, T[] array, glBufferTarget target) where T : struct
|
||||
{
|
||||
return buffer.Extend(new ArraySegment<T>(array), target);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// for buffer with uri read
|
||||
/// </summary>
|
||||
public class UriByteBuffer : IBytesBuffer
|
||||
{
|
||||
public string Uri
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
Byte[] m_bytes;
|
||||
public ArraySegment<byte> GetBytes()
|
||||
{
|
||||
return new ArraySegment<byte>(m_bytes);
|
||||
}
|
||||
|
||||
public UriByteBuffer(string baseDir, string uri)
|
||||
{
|
||||
Uri = uri;
|
||||
m_bytes = ReadFromUri(baseDir, uri);
|
||||
}
|
||||
|
||||
const string DataPrefix = "data:application/octet-stream;base64,";
|
||||
|
||||
const string DataPrefix2 = "data:application/gltf-buffer;base64,";
|
||||
|
||||
const string DataPrefix3 = "data:image/jpeg;base64,";
|
||||
|
||||
[Obsolete("Use ReadEmbedded(uri)")]
|
||||
public static Byte[] ReadEmbeded(string uri)
|
||||
{
|
||||
return ReadEmbedded(uri);
|
||||
}
|
||||
|
||||
public static Byte[] ReadEmbedded(string uri)
|
||||
{
|
||||
var pos = uri.IndexOf(";base64,");
|
||||
if (pos < 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.FromBase64String(uri.Substring(pos + 8));
|
||||
}
|
||||
}
|
||||
|
||||
Byte[] ReadFromUri(string baseDir, string uri)
|
||||
{
|
||||
var bytes = ReadEmbedded(uri);
|
||||
if (bytes != null)
|
||||
{
|
||||
return bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// as local file path
|
||||
return File.ReadAllBytes(Path.Combine(baseDir, uri));
|
||||
}
|
||||
}
|
||||
|
||||
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// for exporter
|
||||
/// </summary>
|
||||
public class ArrayByteBuffer : IBytesBuffer
|
||||
{
|
||||
public string Uri
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
Byte[] m_bytes;
|
||||
int m_used;
|
||||
|
||||
public ArrayByteBuffer(Byte[] bytes = null)
|
||||
{
|
||||
Uri = "";
|
||||
m_bytes = bytes;
|
||||
}
|
||||
|
||||
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
|
||||
{
|
||||
using (var pin = Pin.Create(array))
|
||||
{
|
||||
var elementSize = Marshal.SizeOf(typeof(T));
|
||||
var view = Extend(pin.Ptr, array.Count * elementSize, elementSize, target);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
public glTFBufferView Extend(IntPtr p, int bytesLength, int stride, glBufferTarget target)
|
||||
{
|
||||
var tmp = m_bytes;
|
||||
// alignment
|
||||
var padding = m_used % stride == 0 ? 0 : stride - m_used % stride;
|
||||
|
||||
if (m_bytes == null || m_used + padding + bytesLength > m_bytes.Length)
|
||||
{
|
||||
// recreate buffer
|
||||
m_bytes = new Byte[m_used + padding + bytesLength];
|
||||
if (m_used > 0)
|
||||
{
|
||||
Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
if (m_used + padding + bytesLength > m_bytes.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
Marshal.Copy(p, m_bytes, m_used + padding, bytesLength);
|
||||
var result=new glTFBufferView
|
||||
{
|
||||
buffer = 0,
|
||||
byteLength = bytesLength,
|
||||
byteOffset = m_used + padding,
|
||||
byteStride = stride,
|
||||
target = target,
|
||||
};
|
||||
m_used = m_used + padding + bytesLength;
|
||||
return result;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> GetBytes()
|
||||
{
|
||||
if (m_bytes == null)
|
||||
{
|
||||
return new ArraySegment<byte>();
|
||||
}
|
||||
|
||||
return new ArraySegment<byte>(m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,51 +25,6 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public IStorage Storage;
|
||||
|
||||
public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor)
|
||||
{
|
||||
if (string.IsNullOrEmpty(generatorVersion)) return false;
|
||||
if (generatorVersion == "UniGLTF") return true;
|
||||
if (!generatorVersion.FastStartsWith("UniGLTF-")) return false;
|
||||
|
||||
try
|
||||
{
|
||||
var splitted = generatorVersion.Substring(8).Split('.');
|
||||
var generatorMajor = int.Parse(splitted[0]);
|
||||
var generatorMinor = int.Parse(splitted[1]);
|
||||
|
||||
if (generatorMajor < major)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (generatorMajor > major)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (generatorMinor >= minor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarningFormat("{0}: {1}", generatorVersion, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGeneratedUniGLTFAndOlder(int major, int minor)
|
||||
{
|
||||
if (GLTF == null) return false;
|
||||
if (GLTF.asset == null) return false;
|
||||
return IsGeneratedUniGLTFAndOlderThan(GLTF.asset.generator, major, minor);
|
||||
}
|
||||
|
||||
#region Parse
|
||||
public void ParsePath(string path)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
namespace UniGLTF
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public interface IAnimationImporter
|
||||
{
|
||||
void Import(ImporterContext context);
|
||||
List<AnimationClip> Import(glTF gltf, GameObject root, Axises invertAxis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
using VRMShaders;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
@@ -41,8 +41,6 @@ namespace UniGLTF
|
||||
TextureFactory m_textureFactory;
|
||||
public TextureFactory TextureFactory => m_textureFactory;
|
||||
|
||||
IAwaitCaller m_awaitCaller;
|
||||
|
||||
public ImporterContext(GltfParser parser,
|
||||
IEnumerable<(string, UnityEngine.Object)> externalObjectMap = null)
|
||||
{
|
||||
@@ -81,20 +79,12 @@ namespace UniGLTF
|
||||
{
|
||||
awaitCaller = new TaskCaller();
|
||||
}
|
||||
m_awaitCaller = awaitCaller;
|
||||
|
||||
if (MeasureTime == null)
|
||||
{
|
||||
MeasureTime = new ImporterContextSpeedLog().MeasureTime;
|
||||
}
|
||||
|
||||
var inverter = InvertAxis.Create();
|
||||
|
||||
if (Root == null)
|
||||
{
|
||||
Root = new GameObject("GLTF");
|
||||
}
|
||||
|
||||
if (GLTF.extensionsRequired != null)
|
||||
{
|
||||
var sb = new List<string>();
|
||||
@@ -116,14 +106,28 @@ namespace UniGLTF
|
||||
await LoadMaterialsAsync();
|
||||
}
|
||||
|
||||
await LoadGeometryAsync(awaitCaller, MeasureTime);
|
||||
|
||||
using (MeasureTime("AnimationImporter"))
|
||||
{
|
||||
AnimationClips.AddRange(AnimationImporter.Import(GLTF, Root, InvertAxis));
|
||||
}
|
||||
|
||||
await OnLoadHierarchy(awaitCaller, MeasureTime);
|
||||
}
|
||||
|
||||
protected virtual async Task LoadGeometryAsync(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
|
||||
{
|
||||
var inverter = InvertAxis.Create();
|
||||
|
||||
var meshImporter = new MeshImporter();
|
||||
for (int i = 0; i < GLTF.meshes.Count; ++i)
|
||||
{
|
||||
var index = i;
|
||||
using (MeasureTime("ReadMesh"))
|
||||
{
|
||||
var x = meshImporter.ReadMesh(this, index, inverter);
|
||||
var y = await BuildMeshAsync(MeasureTime, x, index);
|
||||
var x = meshImporter.ReadMesh(GLTF, index, inverter);
|
||||
var y = await BuildMeshAsync(awaitCaller, MeasureTime, x, index);
|
||||
Meshes.Add(y);
|
||||
}
|
||||
}
|
||||
@@ -135,14 +139,14 @@ namespace UniGLTF
|
||||
Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform);
|
||||
}
|
||||
}
|
||||
await m_awaitCaller.NextFrame();
|
||||
await awaitCaller.NextFrame();
|
||||
|
||||
using (MeasureTime("BuildHierarchy"))
|
||||
{
|
||||
var nodes = new List<NodeImporter.TransformWithSkin>();
|
||||
for (int i = 0; i < Nodes.Count; ++i)
|
||||
{
|
||||
nodes.Add(NodeImporter.BuildHierarchy(this, i));
|
||||
nodes.Add(NodeImporter.BuildHierarchy(GLTF, i, Nodes, Meshes));
|
||||
}
|
||||
|
||||
NodeImporter.FixCoordinate(this, nodes, inverter);
|
||||
@@ -153,6 +157,10 @@ namespace UniGLTF
|
||||
NodeImporter.SetupSkinning(this, nodes, i, inverter);
|
||||
}
|
||||
|
||||
if (Root == null)
|
||||
{
|
||||
Root = new GameObject("GLTF");
|
||||
}
|
||||
if (GLTF.rootnodes != null)
|
||||
{
|
||||
// connect root
|
||||
@@ -163,14 +171,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
}
|
||||
await m_awaitCaller.NextFrame();
|
||||
|
||||
using (MeasureTime("AnimationImporter"))
|
||||
{
|
||||
AnimationImporter.Import(this);
|
||||
}
|
||||
|
||||
await OnLoadModel(m_awaitCaller, MeasureTime);
|
||||
await awaitCaller.NextFrame();
|
||||
}
|
||||
|
||||
public async Task LoadMaterialsAsync()
|
||||
@@ -191,17 +192,17 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Task OnLoadModel(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
|
||||
protected virtual Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
|
||||
{
|
||||
// do nothing
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
|
||||
async Task<MeshWithMaterials> BuildMeshAsync(Func<string, IDisposable> MeasureTime, MeshImporter.MeshContext x, int i)
|
||||
async Task<MeshWithMaterials> BuildMeshAsync(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime, MeshImporter.MeshContext x, int i)
|
||||
{
|
||||
using (MeasureTime("BuildMesh"))
|
||||
{
|
||||
var meshWithMaterials = await MeshImporter.BuildMeshAsync(m_awaitCaller, MaterialFactory, x);
|
||||
var meshWithMaterials = await MeshImporter.BuildMeshAsync(awaitCaller, MaterialFactory, x);
|
||||
var mesh = meshWithMaterials.Mesh;
|
||||
|
||||
// mesh name
|
||||
|
||||
@@ -4,7 +4,7 @@ using VRMShaders;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public delegate IEnumerable<TextureImportParam> TextureEnumerator(GltfParser parser);
|
||||
public delegate IEnumerable<TextureImportParam> EnumerateAllTexturesDistinctFunc(GltfParser parser);
|
||||
|
||||
/// <summary>
|
||||
/// Texture 生成に関して
|
||||
@@ -34,8 +34,10 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public static class GltfTextureEnumerator
|
||||
{
|
||||
public static IEnumerable<TextureImportParam> EnumerateTextures(GltfParser parser, glTFMaterial m)
|
||||
public static IEnumerable<TextureImportParam> EnumerateTexturesForMaterial(GltfParser parser, int i)
|
||||
{
|
||||
var m = parser.GLTF.materials[i];
|
||||
|
||||
int? metallicRoughnessTexture = default;
|
||||
if (m.pbrMetallicRoughness != null)
|
||||
{
|
||||
@@ -79,14 +81,20 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TextureImportParam> Enumerate(GltfParser parser)
|
||||
/// <summary>
|
||||
/// glTF 全体で使うテクスチャーをユニークになるように列挙する
|
||||
/// </summary>
|
||||
/// <param name="parser"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<TextureImportParam> EnumerateAllTexturesDistinct(GltfParser parser)
|
||||
{
|
||||
var used = new HashSet<string>();
|
||||
foreach (var material in parser.GLTF.materials)
|
||||
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
|
||||
{
|
||||
foreach (var textureInfo in EnumerateTextures(parser, material))
|
||||
foreach (var textureInfo in EnumerateTexturesForMaterial(parser, i))
|
||||
{
|
||||
if(used.Add(textureInfo.ExtractKey)){
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace UniGLTF
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="gltfMesh"></param>
|
||||
/// <returns></returns>
|
||||
public void ImportMeshIndependentVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
public void ImportMeshIndependentVertexBuffer(glTF gltf, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
{
|
||||
foreach (var prim in gltfMesh.primitives)
|
||||
{
|
||||
@@ -132,14 +132,14 @@ namespace UniGLTF
|
||||
var indexBuffer = prim.indices;
|
||||
|
||||
// position は必ずある
|
||||
var positions = ctx.GLTF.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION);
|
||||
var positions = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION);
|
||||
var fillLength = m_positions.Count;
|
||||
m_positions.AddRange(positions.Select(inverter.InvertVector3));
|
||||
|
||||
// normal
|
||||
if (prim.attributes.NORMAL != -1)
|
||||
{
|
||||
var normals = ctx.GLTF.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL);
|
||||
var normals = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL);
|
||||
if (normals.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -151,7 +151,7 @@ namespace UniGLTF
|
||||
#if false
|
||||
if (prim.attributes.TANGENT != -1)
|
||||
{
|
||||
var tangents = ctx.GLTF.GetArrayFromAccessor<Vector4>(prim.attributes.TANGENT);
|
||||
var tangents = gltf.GetArrayFromAccessor<Vector4>(prim.attributes.TANGENT);
|
||||
if (tangents.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -164,12 +164,12 @@ namespace UniGLTF
|
||||
// uv
|
||||
if (prim.attributes.TEXCOORD_0 != -1)
|
||||
{
|
||||
var uvs = ctx.GLTF.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0);
|
||||
var uvs = gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0);
|
||||
if (uvs.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
}
|
||||
if (ctx.Parser.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
if (gltf.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
// backward compatibility
|
||||
@@ -187,7 +187,7 @@ namespace UniGLTF
|
||||
// uv2
|
||||
if (prim.attributes.TEXCOORD_1 != -1)
|
||||
{
|
||||
var uvs = ctx.GLTF.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1);
|
||||
var uvs = gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1);
|
||||
if (uvs.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -199,7 +199,7 @@ namespace UniGLTF
|
||||
// color
|
||||
if (prim.attributes.COLOR_0 != -1)
|
||||
{
|
||||
var colors = ctx.GLTF.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0);
|
||||
var colors = gltf.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0);
|
||||
if (colors.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -211,8 +211,8 @@ namespace UniGLTF
|
||||
// skin
|
||||
if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
|
||||
{
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(ctx.GLTF, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(ctx.GLTF, prim.attributes.WEIGHTS_0);
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(gltf, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(gltf, prim.attributes.WEIGHTS_0);
|
||||
if (jointsLength != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -256,7 +256,7 @@ namespace UniGLTF
|
||||
var blendShape = new BlendShape(i.ToString());
|
||||
if (primTarget.POSITION != -1)
|
||||
{
|
||||
var array = ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.POSITION);
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.POSITION);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -266,7 +266,7 @@ namespace UniGLTF
|
||||
}
|
||||
if (primTarget.NORMAL != -1)
|
||||
{
|
||||
var array = ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.NORMAL);
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.NORMAL);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -276,7 +276,7 @@ namespace UniGLTF
|
||||
}
|
||||
if (primTarget.TANGENT != -1)
|
||||
{
|
||||
var array = ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.TANGENT);
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.TANGENT);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -290,7 +290,7 @@ namespace UniGLTF
|
||||
|
||||
var indices =
|
||||
(indexBuffer >= 0)
|
||||
? ctx.GLTF.GetIndices(indexBuffer)
|
||||
? gltf.GetIndices(indexBuffer)
|
||||
: TriangleUtil.FlipTriangle(Enumerable.Range(0, m_positions.Count)).ToArray() // without index array
|
||||
;
|
||||
for (int i = 0; i < indices.Length; ++i)
|
||||
@@ -313,55 +313,55 @@ namespace UniGLTF
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="gltfMesh"></param>
|
||||
/// <returns></returns>
|
||||
public void ImportMeshSharingVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
public void ImportMeshSharingVertexBuffer(glTF gltf, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
{
|
||||
{
|
||||
// 同じVertexBufferを共有しているので先頭のモノを使う
|
||||
var prim = gltfMesh.primitives.First();
|
||||
m_positions.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION).SelectInplace(inverter.InvertVector3));
|
||||
m_positions.AddRange(gltf.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION).SelectInplace(inverter.InvertVector3));
|
||||
|
||||
// normal
|
||||
if (prim.attributes.NORMAL != -1)
|
||||
{
|
||||
m_normals.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL).SelectInplace(inverter.InvertVector3));
|
||||
m_normals.AddRange(gltf.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL).SelectInplace(inverter.InvertVector3));
|
||||
}
|
||||
|
||||
#if false
|
||||
// tangent
|
||||
if (prim.attributes.TANGENT != -1)
|
||||
{
|
||||
tangents.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector4>(prim.attributes.TANGENT).SelectInplace(inverter.InvertVector4));
|
||||
tangents.AddRange(gltf.GetArrayFromAccessor<Vector4>(prim.attributes.TANGENT).SelectInplace(inverter.InvertVector4));
|
||||
}
|
||||
#endif
|
||||
|
||||
// uv
|
||||
if (prim.attributes.TEXCOORD_0 != -1)
|
||||
{
|
||||
if (ctx.Parser.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
if (gltf.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
// backward compatibility
|
||||
m_uv.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()));
|
||||
m_uv.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()));
|
||||
#pragma warning restore 0612
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uv.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()));
|
||||
m_uv.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()));
|
||||
}
|
||||
}
|
||||
|
||||
// uv2
|
||||
if (prim.attributes.TEXCOORD_1 != -1)
|
||||
{
|
||||
m_uv2.AddRange(ctx.GLTF.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1).SelectInplace(x => x.ReverseUV()));
|
||||
m_uv2.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1).SelectInplace(x => x.ReverseUV()));
|
||||
}
|
||||
|
||||
// color
|
||||
if (prim.attributes.COLOR_0 != -1)
|
||||
{
|
||||
if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 3)
|
||||
if (gltf.accessors[prim.attributes.COLOR_0].TypeCount == 3)
|
||||
{
|
||||
var vec3Color = ctx.GLTF.GetArrayFromAccessor<Vector3>(prim.attributes.COLOR_0);
|
||||
var vec3Color = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.COLOR_0);
|
||||
m_colors.AddRange(new Color[vec3Color.Length]);
|
||||
|
||||
for (int i = 0; i < vec3Color.Length; i++)
|
||||
@@ -370,21 +370,21 @@ namespace UniGLTF
|
||||
m_colors[i] = new Color(color.x, color.y, color.z);
|
||||
}
|
||||
}
|
||||
else if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 4)
|
||||
else if (gltf.accessors[prim.attributes.COLOR_0].TypeCount == 4)
|
||||
{
|
||||
m_colors.AddRange(ctx.GLTF.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0));
|
||||
m_colors.AddRange(gltf.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException(string.Format("unknown color type {0}", ctx.GLTF.accessors[prim.attributes.COLOR_0].type));
|
||||
throw new NotImplementedException(string.Format("unknown color type {0}", gltf.accessors[prim.attributes.COLOR_0].type));
|
||||
}
|
||||
}
|
||||
|
||||
// skin
|
||||
if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
|
||||
{
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(ctx.GLTF, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(ctx.GLTF, prim.attributes.WEIGHTS_0);
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(gltf, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(gltf, prim.attributes.WEIGHTS_0);
|
||||
|
||||
for (int j = 0; j < jointsLength; ++j)
|
||||
{
|
||||
@@ -424,17 +424,17 @@ namespace UniGLTF
|
||||
if (primTarget.POSITION != -1)
|
||||
{
|
||||
blendShape.Positions.Assign(
|
||||
ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.POSITION), inverter.InvertVector3);
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.POSITION), inverter.InvertVector3);
|
||||
}
|
||||
if (primTarget.NORMAL != -1)
|
||||
{
|
||||
blendShape.Normals.Assign(
|
||||
ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.NORMAL), inverter.InvertVector3);
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.NORMAL), inverter.InvertVector3);
|
||||
}
|
||||
if (primTarget.TANGENT != -1)
|
||||
{
|
||||
blendShape.Tangents.Assign(
|
||||
ctx.GLTF.GetArrayFromAccessor<Vector3>(primTarget.TANGENT), inverter.InvertVector3);
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.TANGENT), inverter.InvertVector3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,7 +448,7 @@ namespace UniGLTF
|
||||
}
|
||||
else
|
||||
{
|
||||
var indices = ctx.GLTF.GetIndices(prim.indices);
|
||||
var indices = gltf.GetIndices(prim.indices);
|
||||
m_subMeshes.Add(indices);
|
||||
}
|
||||
|
||||
@@ -530,18 +530,18 @@ namespace UniGLTF
|
||||
return sharedAttributes;
|
||||
}
|
||||
|
||||
public MeshContext ReadMesh(ImporterContext ctx, int meshIndex, IAxisInverter inverter)
|
||||
public MeshContext ReadMesh(glTF gltf, int meshIndex, IAxisInverter inverter)
|
||||
{
|
||||
var gltfMesh = ctx.GLTF.meshes[meshIndex];
|
||||
var gltfMesh = gltf.meshes[meshIndex];
|
||||
|
||||
var meshContext = new MeshContext(gltfMesh.name, meshIndex);
|
||||
if (HasSharedVertexBuffer(gltfMesh))
|
||||
{
|
||||
meshContext.ImportMeshSharingVertexBuffer(ctx, gltfMesh, inverter);
|
||||
meshContext.ImportMeshSharingVertexBuffer(gltf, gltfMesh, inverter);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshContext.ImportMeshIndependentVertexBuffer(ctx, gltfMesh, inverter);
|
||||
meshContext.ImportMeshIndependentVertexBuffer(gltf, gltfMesh, inverter);
|
||||
}
|
||||
|
||||
meshContext.RenameBlendShape(gltfMesh);
|
||||
|
||||
@@ -64,9 +64,9 @@ namespace UniGLTF
|
||||
public int? SkinIndex;
|
||||
}
|
||||
|
||||
public static TransformWithSkin BuildHierarchy(ImporterContext context, int i)
|
||||
public static TransformWithSkin BuildHierarchy(glTF gltf, int i, List<Transform> nodes, List<MeshWithMaterials> meshes)
|
||||
{
|
||||
var go = context.Nodes[i].gameObject;
|
||||
var go = nodes[i].gameObject;
|
||||
if (string.IsNullOrEmpty(go.name))
|
||||
{
|
||||
go.name = string.Format("node{0:000}", i);
|
||||
@@ -80,12 +80,12 @@ namespace UniGLTF
|
||||
//
|
||||
// build hierarchy
|
||||
//
|
||||
var node = context.GLTF.nodes[i];
|
||||
var node = gltf.nodes[i];
|
||||
if (node.children != null)
|
||||
{
|
||||
foreach (var child in node.children)
|
||||
{
|
||||
context.Nodes[child].transform.SetParent(context.Nodes[i].transform,
|
||||
nodes[child].transform.SetParent(nodes[i].transform,
|
||||
false // node has local transform
|
||||
);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace UniGLTF
|
||||
//
|
||||
if (node.mesh != -1)
|
||||
{
|
||||
var mesh = context.Meshes[node.mesh];
|
||||
var mesh = meshes[node.mesh];
|
||||
if (mesh.Mesh.blendShapeCount == 0 && node.skin == -1)
|
||||
{
|
||||
// without blendshape and bone skinning
|
||||
|
||||
@@ -6,28 +6,28 @@ namespace UniGLTF
|
||||
{
|
||||
public sealed class RootAnimationImporter : IAnimationImporter
|
||||
{
|
||||
public void Import(ImporterContext context)
|
||||
public List<AnimationClip> Import(glTF gltf, GameObject root, Axises invertAxis)
|
||||
{
|
||||
// animation
|
||||
if (context.GLTF.animations != null && context.GLTF.animations.Any())
|
||||
var animationClips = new List<AnimationClip>();
|
||||
if (gltf.animations != null && gltf.animations.Any())
|
||||
{
|
||||
var animation = context.Root.AddComponent<Animation>();
|
||||
context.AnimationClips = ImportAnimationClips(context.GLTF, context.InvertAxis);
|
||||
var animation = root.AddComponent<Animation>();
|
||||
animationClips.AddRange(ImportAnimationClips(gltf, invertAxis));
|
||||
|
||||
foreach (var clip in context.AnimationClips)
|
||||
foreach (var clip in animationClips)
|
||||
{
|
||||
animation.AddClip(clip, clip.name);
|
||||
}
|
||||
if (context.AnimationClips.Count > 0)
|
||||
if (animationClips.Count > 0)
|
||||
{
|
||||
animation.clip = context.AnimationClips.First();
|
||||
animation.clip = animationClips.First();
|
||||
}
|
||||
}
|
||||
return animationClips;
|
||||
}
|
||||
|
||||
private List<AnimationClip> ImportAnimationClips(glTF gltf, Axises invertAxis)
|
||||
private IEnumerable<AnimationClip> ImportAnimationClips(glTF gltf, Axises invertAxis)
|
||||
{
|
||||
var animationClips = new List<AnimationClip>();
|
||||
for (var i = 0; i < gltf.animations.Count; ++i)
|
||||
{
|
||||
var clip = new AnimationClip();
|
||||
@@ -46,10 +46,8 @@ namespace UniGLTF
|
||||
animation.name = $"animation:{i}";
|
||||
}
|
||||
|
||||
animationClips.Add(AnimationImporterUtil.ConvertAnimationClip(gltf, animation, invertAxis.Create()));
|
||||
yield return AnimationImporterUtil.ConvertAnimationClip(gltf, animation, invertAxis.Create());
|
||||
}
|
||||
|
||||
return animationClips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public static class GltfTextureImporter
|
||||
{
|
||||
static Byte[] ToArray(ArraySegment<byte> bytes)
|
||||
public static Byte[] ToArray(ArraySegment<byte> bytes)
|
||||
{
|
||||
if (bytes.Array == null)
|
||||
{
|
||||
|
||||
75
Assets/UniGLTF/Runtime/UniGLTF/IO/UriByteBuffer.cs
Normal file
75
Assets/UniGLTF/Runtime/UniGLTF/IO/UriByteBuffer.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// for buffer with uri read
|
||||
/// </summary>
|
||||
public class UriByteBuffer : IBytesBuffer
|
||||
{
|
||||
public string Uri
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
Byte[] m_bytes;
|
||||
public ArraySegment<byte> Bytes => new ArraySegment<byte>(m_bytes);
|
||||
|
||||
public UriByteBuffer(string baseDir, string uri)
|
||||
{
|
||||
Uri = uri;
|
||||
m_bytes = ReadFromUri(baseDir, uri);
|
||||
}
|
||||
|
||||
const string DataPrefix = "data:application/octet-stream;base64,";
|
||||
|
||||
const string DataPrefix2 = "data:application/gltf-buffer;base64,";
|
||||
|
||||
const string DataPrefix3 = "data:image/jpeg;base64,";
|
||||
|
||||
[Obsolete("Use ReadEmbedded(uri)")]
|
||||
public static Byte[] ReadEmbeded(string uri)
|
||||
{
|
||||
return ReadEmbedded(uri);
|
||||
}
|
||||
|
||||
public static Byte[] ReadEmbedded(string uri)
|
||||
{
|
||||
var pos = uri.IndexOf(";base64,");
|
||||
if (pos < 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.FromBase64String(uri.Substring(pos + 8));
|
||||
}
|
||||
}
|
||||
|
||||
Byte[] ReadFromUri(string baseDir, string uri)
|
||||
{
|
||||
var bytes = ReadEmbedded(uri);
|
||||
if (bytes != null)
|
||||
{
|
||||
return bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// as local file path
|
||||
return File.ReadAllBytes(Path.Combine(baseDir, uri));
|
||||
}
|
||||
}
|
||||
|
||||
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ExtendCapacity(int capacity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e9c9201942704b4f9dd050115073032
|
||||
guid: 8b75aca0e4a7415418cd1c3d018483b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -66,6 +66,27 @@ namespace UniJSON
|
||||
return self.ContainsKey(ukey);
|
||||
}
|
||||
|
||||
public static bool TryGet(this JsonNode self, Utf8String key, out JsonNode found)
|
||||
{
|
||||
foreach (var kv in self.ObjectItems())
|
||||
{
|
||||
if (kv.Key.GetUtf8String() == key)
|
||||
{
|
||||
found = kv.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
found = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGet(this JsonNode self, String key, out JsonNode found)
|
||||
{
|
||||
var ukey = Utf8String.From(key);
|
||||
return self.TryGet(ukey, out found);
|
||||
}
|
||||
|
||||
public static Utf8String KeyOf(this JsonNode self, JsonNode node)
|
||||
{
|
||||
foreach (var kv in self.ObjectItems())
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
// should unique
|
||||
var gltfTextures = GltfTextureEnumerator.Enumerate(parser).ToArray();
|
||||
var gltfTextures = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
var distinct = gltfTextures.Distinct().ToArray();
|
||||
Assert.True(gltfTextures.SequenceEqual(distinct));
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace UniGLTF
|
||||
{
|
||||
GLTF = TwoTexture(),
|
||||
};
|
||||
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
|
||||
var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
Assert.AreEqual(2, items.Length);
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ namespace UniGLTF
|
||||
{
|
||||
GLTF = TwoTextureOneUri(),
|
||||
};
|
||||
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
|
||||
var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
Assert.AreEqual(1, items.Length);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace UniGLTF
|
||||
{
|
||||
GLTF = TwoTextureOneImage(),
|
||||
};
|
||||
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
|
||||
var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
Assert.AreEqual(1, items.Length);
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace UniGLTF
|
||||
{
|
||||
GLTF = CombineMetallicSmoothOcclusion(),
|
||||
};
|
||||
var items = GltfTextureEnumerator.Enumerate(parser).ToArray();
|
||||
var items = GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
Assert.AreEqual(1, items.Length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,12 +185,12 @@ namespace UniGLTF
|
||||
[Test]
|
||||
public void VersionChecker()
|
||||
{
|
||||
Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16));
|
||||
Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16));
|
||||
Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16));
|
||||
Assert.False(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16));
|
||||
Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16));
|
||||
Assert.True(GltfParser.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16));
|
||||
Assert.False(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("hoge", 1, 16));
|
||||
Assert.False(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.16", 1, 16));
|
||||
Assert.True(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("UniGLTF-1.15", 1, 16));
|
||||
Assert.False(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("UniGLTF-11.16", 1, 16));
|
||||
Assert.True(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("UniGLTF-0.16", 1, 16));
|
||||
Assert.True(glTFExtensions.IsGeneratedUniGLTFAndOlderThan("UniGLTF", 1, 16));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -149,9 +149,9 @@ namespace VRM
|
||||
.Where(x => x.IsUsed)
|
||||
.Select(x => x.Texture)
|
||||
.ToArray();
|
||||
var vrmTextures = new VRMTextureEnumerator(m_context.VRM);
|
||||
var vrmTextures = new VRMMtoonMaterialImporter(m_context.VRM);
|
||||
var dirName = $"{m_prefabPath.FileNameWithoutExtension}.Textures";
|
||||
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.Enumerate, subAssets, _ => { }, onTextureReloaded);
|
||||
TextureExtractor.ExtractTextures(m_context.Parser, m_prefabPath.Parent.Child(dirName), vrmTextures.EnumerateAllTexturesDistinct, subAssets, _ => { }, onTextureReloaded);
|
||||
}
|
||||
|
||||
bool SaveAsAsset(UnityEngine.Object o)
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace VRM
|
||||
using (var context = new VRMImporterContext(parser, map))
|
||||
{
|
||||
var editor = new VRMEditorImporterContext(context, prefabPath);
|
||||
foreach (var textureInfo in new VRMTextureEnumerator(context.VRM).Enumerate(parser))
|
||||
foreach (var textureInfo in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
|
||||
{
|
||||
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace VRM
|
||||
using (var context = new VRMImporterContext(parser, map))
|
||||
{
|
||||
var editor = new VRMEditorImporterContext(context, prefabPath);
|
||||
foreach (var textureInfo in new VRMTextureEnumerator(context.VRM).Enumerate(parser))
|
||||
foreach (var textureInfo in new VRMMtoonMaterialImporter(context.VRM).EnumerateAllTexturesDistinct(parser))
|
||||
{
|
||||
TextureImporterConfigurator.Configure(textureInfo, map.ToDictionary(x => x.name, x => x.texture as Texture2D));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace VRM
|
||||
{
|
||||
VRM = vrm;
|
||||
// override material importer
|
||||
GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, new MToonMaterialImporter(VRM.materialProperties).TryCreateParam);
|
||||
GltfMaterialImporter.GltfMaterialParamProcessors.Insert(0, new VRMMtoonMaterialImporter(VRM).TryCreateParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace VRM
|
||||
}
|
||||
|
||||
#region OnLoad
|
||||
protected override async Task OnLoadModel(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
|
||||
protected override async Task OnLoadHierarchy(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
|
||||
{
|
||||
Root.name = "VRM";
|
||||
|
||||
|
||||
@@ -3,13 +3,19 @@ using UniGLTF;
|
||||
using UnityEngine;
|
||||
using VRMShaders;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class MToonMaterialImporter
|
||||
public class VRMMtoonMaterialImporter
|
||||
{
|
||||
public static bool TryCreateParam(GltfParser parser, int i, glTF_VRM_Material vrmMaterial, out MaterialImportParam param)
|
||||
readonly glTF_VRM_extensions m_vrm;
|
||||
public VRMMtoonMaterialImporter(glTF_VRM_extensions vrm)
|
||||
{
|
||||
m_vrm = vrm;
|
||||
}
|
||||
|
||||
public bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param)
|
||||
{
|
||||
var vrmMaterial = m_vrm.materialProperties[i];
|
||||
if (vrmMaterial.shader == VRM.glTF_VRM_Material.VRM_USE_GLTFSHADER)
|
||||
{
|
||||
// fallback to gltf
|
||||
@@ -87,21 +93,64 @@ namespace VRM
|
||||
return true;
|
||||
}
|
||||
|
||||
List<glTF_VRM_Material> m_materials;
|
||||
public MToonMaterialImporter(List<glTF_VRM_Material> materials)
|
||||
public IEnumerable<TextureImportParam> EnumerateTexturesForMaterial(GltfParser parser, int i)
|
||||
{
|
||||
m_materials = materials;
|
||||
}
|
||||
|
||||
public bool TryCreateParam(GltfParser parser, int i, out MaterialImportParam param)
|
||||
{
|
||||
if (TryCreateParam(parser, i, m_materials[i], out param))
|
||||
// mtoon
|
||||
if (!TryCreateParam(parser, i, out MaterialImportParam param))
|
||||
{
|
||||
return true;
|
||||
// unlit
|
||||
if (!GltfUnlitMaterial.TryCreateParam(parser, i, out param))
|
||||
{
|
||||
// pbr
|
||||
GltfPBRMaterial.TryCreateParam(parser, i, out param);
|
||||
}
|
||||
}
|
||||
|
||||
param = default;
|
||||
return false;
|
||||
foreach (var kv in param.TextureSlots)
|
||||
{
|
||||
yield return kv.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TextureImportParam> EnumerateAllTexturesDistinct(GltfParser parser)
|
||||
{
|
||||
var used = new HashSet<string>();
|
||||
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
|
||||
{
|
||||
var vrmMaterial = m_vrm.materialProperties[i];
|
||||
if (vrmMaterial.shader == MToon.Utils.ShaderName)
|
||||
{
|
||||
// MToon
|
||||
foreach (var textureInfo in EnumerateTexturesForMaterial(parser, i))
|
||||
{
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// PBR or Unlit
|
||||
foreach (var textureInfo in GltfTextureEnumerator.EnumerateTexturesForMaterial(parser, i))
|
||||
{
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// thumbnail
|
||||
if (m_vrm.meta != null && m_vrm.meta.texture != -1)
|
||||
{
|
||||
var textureInfo = GltfTextureImporter.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e6d15fc36df79649bb4724b06b5eae3
|
||||
guid: bad75b40d017eb74ba79f561d22dc372
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,83 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF;
|
||||
using UnityEngine;
|
||||
using VRMShaders;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VRMTextureEnumerator
|
||||
{
|
||||
readonly glTF_VRM_extensions m_vrm;
|
||||
public VRMTextureEnumerator(glTF_VRM_extensions vrm)
|
||||
{
|
||||
m_vrm = vrm;
|
||||
}
|
||||
|
||||
public IEnumerable<TextureImportParam> EnumerateMaterial(GltfParser parser, glTF_VRM_Material vrmMaterial)
|
||||
{
|
||||
// MToon
|
||||
var offsetScaleMap = new Dictionary<string, float[]>();
|
||||
foreach (var kv in vrmMaterial.vectorProperties)
|
||||
{
|
||||
if (vrmMaterial.textureProperties.ContainsKey(kv.Key))
|
||||
{
|
||||
// texture offset & scale
|
||||
offsetScaleMap.Add(kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
foreach (var kv in vrmMaterial.textureProperties)
|
||||
{
|
||||
var (offset, scale) = (Vector2.zero, Vector2.one);
|
||||
if (offsetScaleMap.TryGetValue(kv.Key, out float[] value))
|
||||
{
|
||||
offset = new Vector2(value[0], value[1]);
|
||||
scale = new Vector2(value[2], value[3]);
|
||||
}
|
||||
|
||||
// SRGB color or normalmap
|
||||
yield return MToonTextureParam.Create(parser, kv.Value, offset, scale, kv.Key, default, default);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TextureImportParam> Enumerate(GltfParser parser)
|
||||
{
|
||||
var used = new HashSet<string>();
|
||||
for (int i = 0; i < parser.GLTF.materials.Count; ++i)
|
||||
{
|
||||
var vrmMaterial = m_vrm.materialProperties[i];
|
||||
if (vrmMaterial.shader == MToon.Utils.ShaderName)
|
||||
{
|
||||
// MToon
|
||||
foreach(var textureInfo in EnumerateMaterial(parser, vrmMaterial))
|
||||
{
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// PBR or Unlit
|
||||
foreach (var textureInfo in GltfTextureEnumerator.EnumerateTextures(parser, parser.GLTF.materials[i]))
|
||||
{
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// thumbnail
|
||||
if (m_vrm.meta != null && m_vrm.meta.texture != -1)
|
||||
{
|
||||
var textureInfo = GltfTextureImporter.CreateSRGB(parser, m_vrm.meta.texture, Vector2.zero, Vector2.one);
|
||||
if (used.Add(textureInfo.ExtractKey))
|
||||
{
|
||||
yield return textureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,15 @@ namespace VRM
|
||||
srcMaterial.mainTexture = tex0;
|
||||
srcMaterial.mainTextureOffset = offset;
|
||||
srcMaterial.mainTextureScale = scale;
|
||||
|
||||
|
||||
var materialExporter = new VRMMaterialExporter();
|
||||
var vrmMaterial = VRMMaterialExporter.CreateFromMaterial(srcMaterial, textureManager);
|
||||
Assert.AreEqual(vrmMaterial.vectorProperties["_MainTex"], new float[]{0.3f, 0.2f, 0.5f, 0.6f});
|
||||
|
||||
var materialImporter = new MToonMaterialImporter(new System.Collections.Generic.List<glTF_VRM_Material>{ vrmMaterial });
|
||||
Assert.AreEqual(vrmMaterial.vectorProperties["_MainTex"], new float[] { 0.3f, 0.2f, 0.5f, 0.6f });
|
||||
|
||||
var materialImporter = new VRMMtoonMaterialImporter(new glTF_VRM_extensions
|
||||
{
|
||||
materialProperties = new System.Collections.Generic.List<glTF_VRM_Material> { vrmMaterial }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace VRM
|
||||
},
|
||||
}
|
||||
};
|
||||
var items = new VRMTextureEnumerator(vrm).Enumerate(parser).ToArray();
|
||||
var items = new VRMMtoonMaterialImporter(vrm).EnumerateAllTexturesDistinct(parser).ToArray();
|
||||
Assert.AreEqual(1, items.Length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace UniVRM10.Samples
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator RoutineNest(VrmLib.ExpressionPreset preset, float velocity, float wait)
|
||||
IEnumerator RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset, float velocity, float wait)
|
||||
{
|
||||
for (var value = 0.0f; value <= 1.0f; value += velocity)
|
||||
{
|
||||
@@ -52,11 +52,11 @@ namespace UniVRM10.Samples
|
||||
|
||||
var velocity = 0.1f;
|
||||
|
||||
yield return RoutineNest(VrmLib.ExpressionPreset.Aa, velocity, m_wait);
|
||||
yield return RoutineNest(VrmLib.ExpressionPreset.Ih, velocity, m_wait);
|
||||
yield return RoutineNest(VrmLib.ExpressionPreset.Ou, velocity, m_wait);
|
||||
yield return RoutineNest(VrmLib.ExpressionPreset.Ee, velocity, m_wait);
|
||||
yield return RoutineNest(VrmLib.ExpressionPreset.Oh, velocity, m_wait);
|
||||
yield return RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.aa, velocity, m_wait);
|
||||
yield return RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ih, velocity, m_wait);
|
||||
yield return RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ou, velocity, m_wait);
|
||||
yield return RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ee, velocity, m_wait);
|
||||
yield return RoutineNest(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.oh, velocity, m_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,10 @@ namespace UniVRM10.Samples
|
||||
break;
|
||||
}
|
||||
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(VrmLib.ExpressionPreset.Blink), value);
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
|
||||
yield return null;
|
||||
}
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(VrmLib.ExpressionPreset.Blink), 1.0f);
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 1.0f);
|
||||
|
||||
// wait...
|
||||
yield return new WaitForSeconds(ClosingTime);
|
||||
@@ -91,10 +91,10 @@ namespace UniVRM10.Samples
|
||||
break;
|
||||
}
|
||||
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(VrmLib.ExpressionPreset.Blink), value);
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), value);
|
||||
yield return null;
|
||||
}
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(VrmLib.ExpressionPreset.Blink), 0);
|
||||
m_controller.Expression.SetWeight(ExpressionKey.CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,16 +84,18 @@ namespace UniVRM10.Samples
|
||||
m_textDistributionOther.text = "";
|
||||
}
|
||||
|
||||
public void UpdateMeta(VRM10Controller context)
|
||||
public void UpdateMeta(VRM10MetaObject meta)
|
||||
{
|
||||
// var meta = context.ReadMeta(true);
|
||||
var meta = context.Meta;
|
||||
if (meta == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_textModelTitle.text = meta.Name;
|
||||
m_textModelVersion.text = meta.Version;
|
||||
m_textModelAuthor.text = meta.Authors[0];
|
||||
m_textModelContact.text = meta.ContactInformation;
|
||||
m_textModelReference.text = meta.Reference;
|
||||
m_textModelReference.text = meta.References[0];
|
||||
|
||||
m_textPermissionAllowed.text = meta.AllowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.ViolentUsage.ToString();
|
||||
@@ -306,28 +308,17 @@ namespace UniVRM10.Samples
|
||||
{
|
||||
case ".vrm":
|
||||
{
|
||||
// var context = new ImporterContext();
|
||||
var file = File.ReadAllBytes(path);
|
||||
// context.ParseGlb(file);
|
||||
// context.Load();
|
||||
// context.ShowMeshes();
|
||||
// context.EnableUpdateWhenOffscreen();
|
||||
// context.ShowMeshes();
|
||||
var parser = new UniGLTF.GltfParser();
|
||||
parser.ParsePath(path);
|
||||
|
||||
var model = UniVRM10.VrmLoader.CreateVrmModel(file, new FileInfo(path));
|
||||
|
||||
// UniVRM-0.XXのコンポーネントを構築する
|
||||
var assets = UniVRM10.RuntimeUnityBuilder.ToUnityAsset(model, showMesh: false);
|
||||
|
||||
// showRenderer = false のときに後で表示する例
|
||||
foreach (var renderer in assets.Renderers)
|
||||
using (var loader = new RuntimeUnityBuilder(parser))
|
||||
{
|
||||
renderer.enabled = true;
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
}
|
||||
|
||||
UniVRM10.ComponentBuilder.Build10(model, assets);
|
||||
|
||||
SetModel(assets.Root);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -337,12 +328,15 @@ namespace UniVRM10.Samples
|
||||
var parser = new GltfParser();
|
||||
parser.ParseGlb(file);
|
||||
|
||||
var context = new UniGLTF.ImporterContext(parser);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
using (var loader = new UniGLTF.ImporterContext(parser))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
loader.ShowMeshes();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -352,12 +346,15 @@ namespace UniVRM10.Samples
|
||||
var parser = new GltfParser();
|
||||
parser.ParsePath(path);
|
||||
|
||||
var context = new UniGLTF.ImporterContext(parser);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
using (var loader = new UniGLTF.ImporterContext(parser))
|
||||
{
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
loader.EnableUpdateWhenOffscreen();
|
||||
loader.ShowMeshes();
|
||||
var destroyer = loader.DisposeOnGameObjectDestroyed();
|
||||
SetModel(destroyer.gameObject);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -382,19 +379,22 @@ namespace UniVRM10.Samples
|
||||
if (go != null)
|
||||
{
|
||||
m_controller = go.GetComponent<VRM10Controller>();
|
||||
|
||||
m_texts.UpdateMeta(m_controller);
|
||||
|
||||
m_controller.Controller.UpdateType = VRM10Controller.VRM10ControllerImpl.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
if (m_controller != null)
|
||||
{
|
||||
m_loaded = go.AddComponent<HumanPoseTransfer>();
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_lipSync = go.AddComponent<AIUEO>();
|
||||
m_blink = go.AddComponent<Blinker>();
|
||||
m_texts.UpdateMeta(m_controller.Meta);
|
||||
|
||||
m_controller.LookAt.Gaze = m_target.transform;
|
||||
m_controller.Controller.UpdateType = VRM10Controller.VRM10ControllerImpl.UpdateTypes.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
{
|
||||
m_loaded = go.AddComponent<HumanPoseTransfer>();
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_lipSync = go.AddComponent<AIUEO>();
|
||||
m_blink = go.AddComponent<Blinker>();
|
||||
|
||||
m_controller.LookAt.Gaze = m_target.transform;
|
||||
}
|
||||
}
|
||||
|
||||
var animation = go.GetComponent<Animation>();
|
||||
@@ -402,7 +402,6 @@ namespace UniVRM10.Samples
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -275,24 +275,5 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetInfoString()
|
||||
{
|
||||
var expression = CurrentExpression();
|
||||
if (expression == null)
|
||||
{
|
||||
return "no expression";
|
||||
}
|
||||
|
||||
var key = ExpressionKey.CreateFromClip(expression);
|
||||
if (key.Preset != VrmLib.ExpressionPreset.Custom)
|
||||
{
|
||||
return string.Format("Preset: {0}", key.Preset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("Custom: {0}", key.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace UniVRM10
|
||||
|
||||
// 対象のプロパティを enum から選択する
|
||||
var bindTypeProp = property.FindPropertyRelative("BindType");
|
||||
var bindTypes = (VrmLib.MaterialBindType[])Enum.GetValues(typeof(VrmLib.MaterialBindType));
|
||||
var bindTypes = (UniGLTF.Extensions.VRMC_vrm.MaterialColorType[])Enum.GetValues(typeof(UniGLTF.Extensions.VRMC_vrm.MaterialColorType));
|
||||
var bindType = bindTypes[bindTypeProp.enumValueIndex];
|
||||
var newBindType = ExpressionEditorHelper.EnumPopup(rect, bindType);
|
||||
if (newBindType != bindType)
|
||||
|
||||
@@ -58,7 +58,6 @@ namespace UniVRM10
|
||||
m_lookAt = PropGui.FromObject(serializedObject, nameof(m_target.LookAt));
|
||||
m_firstPerson = PropGui.FromObject(serializedObject, nameof(m_target.FirstPerson));
|
||||
m_springBone = PropGui.FromObject(serializedObject, nameof(m_target.SpringBone));
|
||||
m_asset = PropGui.FromObject(serializedObject, nameof(m_target.ModelAsset));
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
@@ -78,7 +77,6 @@ namespace UniVRM10
|
||||
LookAt,
|
||||
FirstPerson,
|
||||
SpringBone,
|
||||
Assets,
|
||||
}
|
||||
Tabs _tab;
|
||||
|
||||
@@ -136,7 +134,7 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
|
||||
// Setup runtime function.
|
||||
m_target.Setup();
|
||||
|
||||
@@ -167,10 +165,6 @@ namespace UniVRM10
|
||||
case Tabs.SpringBone:
|
||||
m_springBone.RecursiveProperty();
|
||||
break;
|
||||
|
||||
case Tabs.Assets:
|
||||
m_asset.RecursiveProperty();
|
||||
break;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
@@ -194,7 +188,7 @@ namespace UniVRM10
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Expression Weights", EditorStyles.boldLabel);
|
||||
|
||||
|
||||
var sliders = m_sliders.Select(x => x.Slider());
|
||||
foreach (var slider in sliders)
|
||||
{
|
||||
@@ -202,7 +196,7 @@ namespace UniVRM10
|
||||
}
|
||||
m_target.Expression.SetWeights(m_expressionKeyWeights);
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Override rates", EditorStyles.boldLabel);
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
|
||||
@@ -8,132 +8,132 @@ namespace UniVRM10
|
||||
{
|
||||
public static class EditorUnityBuilder
|
||||
{
|
||||
static public ModelAsset ToUnityAsset(VrmLib.Model model, string assetPath, IExternalUnityObject scriptedImporter)
|
||||
{
|
||||
var modelAsset = new ModelAsset();
|
||||
CreateTextureAsset(model, modelAsset, scriptedImporter);
|
||||
CreateMaterialAsset(model, modelAsset, scriptedImporter);
|
||||
CreateMeshAsset(model, modelAsset);
|
||||
// static public ModelAsset ToUnityAsset(VrmLib.Model model, string assetPath, IExternalUnityObject scriptedImporter)
|
||||
// {
|
||||
// var modelAsset = new ModelAsset();
|
||||
// CreateTextureAsset(model, modelAsset, scriptedImporter);
|
||||
// CreateMaterialAsset(model, modelAsset, scriptedImporter);
|
||||
// CreateMeshAsset(model, modelAsset);
|
||||
|
||||
// node
|
||||
RuntimeUnityBuilder.CreateNodes(model.Root, null, modelAsset.Map.Nodes);
|
||||
modelAsset.Root = modelAsset.Map.Nodes[model.Root];
|
||||
// // node
|
||||
// RuntimeUnityBuilder.CreateNodes(model.Root, null, modelAsset.Map.Nodes);
|
||||
// modelAsset.Root = modelAsset.Map.Nodes[model.Root];
|
||||
|
||||
// renderer
|
||||
var map = modelAsset.Map;
|
||||
foreach (var (node, go) in map.Nodes)
|
||||
{
|
||||
if (node.MeshGroup is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// // renderer
|
||||
// var map = modelAsset.Map;
|
||||
// foreach (var (node, go) in map.Nodes)
|
||||
// {
|
||||
// if (node.MeshGroup is null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (node.MeshGroup.Meshes.Count > 1)
|
||||
{
|
||||
throw new NotImplementedException("invalid isolated vertexbuffer");
|
||||
}
|
||||
// if (node.MeshGroup.Meshes.Count > 1)
|
||||
// {
|
||||
// throw new NotImplementedException("invalid isolated vertexbuffer");
|
||||
// }
|
||||
|
||||
var renderer = RuntimeUnityBuilder.CreateRenderer(node, go, map);
|
||||
map.Renderers.Add(node, renderer);
|
||||
modelAsset.Renderers.Add(renderer);
|
||||
}
|
||||
// var renderer = RuntimeUnityBuilder.CreateRenderer(node, go, map);
|
||||
// map.Renderers.Add(node, renderer);
|
||||
// modelAsset.Renderers.Add(renderer);
|
||||
// }
|
||||
|
||||
if (model.Vrm != null)
|
||||
{
|
||||
// humanoid
|
||||
var humanoid = modelAsset.Root.AddComponent<MeshUtility.Humanoid>();
|
||||
humanoid.AssignBones(modelAsset.Map.Nodes.Select(x => (x.Key.HumanoidBone.GetValueOrDefault().ToUnity(), x.Value.transform)));
|
||||
modelAsset.HumanoidAvatar = humanoid.CreateAvatar();
|
||||
modelAsset.HumanoidAvatar.name = "VRM";
|
||||
// if (model.Vrm != null)
|
||||
// {
|
||||
// // humanoid
|
||||
// var humanoid = modelAsset.Root.AddComponent<MeshUtility.Humanoid>();
|
||||
// humanoid.AssignBones(modelAsset.Map.Nodes.Select(x => (x.Key.HumanoidBone.GetValueOrDefault().ToUnity(), x.Value.transform)));
|
||||
// modelAsset.HumanoidAvatar = humanoid.CreateAvatar();
|
||||
// modelAsset.HumanoidAvatar.name = "VRM";
|
||||
|
||||
var animator = modelAsset.Root.AddComponent<Animator>();
|
||||
animator.avatar = modelAsset.HumanoidAvatar;
|
||||
}
|
||||
// var animator = modelAsset.Root.AddComponent<Animator>();
|
||||
// animator.avatar = modelAsset.HumanoidAvatar;
|
||||
// }
|
||||
|
||||
return modelAsset;
|
||||
}
|
||||
// return modelAsset;
|
||||
// }
|
||||
|
||||
static private void CreateTextureAsset(VrmLib.Model model, ModelAsset modelAsset, IExternalUnityObject scriptedImporter)
|
||||
{
|
||||
var externalObjects = scriptedImporter.GetExternalUnityObjects<Texture2D>();
|
||||
// static private void CreateTextureAsset(VrmLib.Model model, ModelAsset modelAsset, IExternalUnityObject scriptedImporter)
|
||||
// {
|
||||
// var externalObjects = scriptedImporter.GetExternalUnityObjects<Texture2D>();
|
||||
|
||||
// textures
|
||||
for (int i = 0; i < model.Textures.Count; ++i)
|
||||
{
|
||||
if (model.Textures[i] is VrmLib.ImageTexture imageTexture)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.Textures[i].Name))
|
||||
{
|
||||
model.Textures[i].Name = string.Format("{0}_img{1}", model.Root.Name, i);
|
||||
}
|
||||
if (externalObjects.ContainsKey(model.Textures[i].Name))
|
||||
{
|
||||
modelAsset.Map.Textures.Add(imageTexture, externalObjects[model.Textures[i].Name]);
|
||||
modelAsset.Textures.Add(externalObjects[model.Textures[i].Name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = !string.IsNullOrEmpty(imageTexture.Name)
|
||||
? imageTexture.Name
|
||||
: string.Format("{0}_img{1}", model.Root.Name, i);
|
||||
// // textures
|
||||
// for (int i = 0; i < model.Textures.Count; ++i)
|
||||
// {
|
||||
// if (model.Textures[i] is VrmLib.ImageTexture imageTexture)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(model.Textures[i].Name))
|
||||
// {
|
||||
// model.Textures[i].Name = string.Format("{0}_img{1}", model.Root.Name, i);
|
||||
// }
|
||||
// if (externalObjects.ContainsKey(model.Textures[i].Name))
|
||||
// {
|
||||
// modelAsset.Map.Textures.Add(imageTexture, externalObjects[model.Textures[i].Name]);
|
||||
// modelAsset.Textures.Add(externalObjects[model.Textures[i].Name]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var name = !string.IsNullOrEmpty(imageTexture.Name)
|
||||
// ? imageTexture.Name
|
||||
// : string.Format("{0}_img{1}", model.Root.Name, i);
|
||||
|
||||
var texture = RuntimeUnityBuilder.CreateTexture(imageTexture);
|
||||
texture.name = name;
|
||||
// var texture = RuntimeUnityBuilder.CreateTexture(imageTexture);
|
||||
// texture.name = name;
|
||||
|
||||
modelAsset.Map.Textures.Add(imageTexture, texture);
|
||||
modelAsset.Textures.Add(texture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"{i} not ImageTexture");
|
||||
}
|
||||
}
|
||||
}
|
||||
// modelAsset.Map.Textures.Add(imageTexture, texture);
|
||||
// modelAsset.Textures.Add(texture);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogWarning($"{i} not ImageTexture");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
static private void CreateMaterialAsset(VrmLib.Model model, ModelAsset modelAsset, IExternalUnityObject scriptedImporter)
|
||||
{
|
||||
var externalObjects = scriptedImporter.GetExternalUnityObjects<UnityEngine.Material>();
|
||||
// static private void CreateMaterialAsset(VrmLib.Model model, ModelAsset modelAsset, IExternalUnityObject scriptedImporter)
|
||||
// {
|
||||
// var externalObjects = scriptedImporter.GetExternalUnityObjects<UnityEngine.Material>();
|
||||
|
||||
foreach (var src in model.Materials)
|
||||
{
|
||||
if (externalObjects.ContainsKey(src.Name))
|
||||
{
|
||||
modelAsset.Map.Materials.Add(src, externalObjects[src.Name]);
|
||||
modelAsset.Materials.Add(externalObjects[src.Name]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: material has VertexColor
|
||||
var material = RuntimeUnityMaterialBuilder.CreateMaterialAsset(src, hasVertexColor: false, modelAsset.Map.Textures);
|
||||
material.name = src.Name;
|
||||
modelAsset.Map.Materials.Add(src, material);
|
||||
modelAsset.Materials.Add(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
// foreach (var src in model.Materials)
|
||||
// {
|
||||
// if (externalObjects.ContainsKey(src.Name))
|
||||
// {
|
||||
// modelAsset.Map.Materials.Add(src, externalObjects[src.Name]);
|
||||
// modelAsset.Materials.Add(externalObjects[src.Name]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // TODO: material has VertexColor
|
||||
// var material = RuntimeUnityMaterialBuilder.CreateMaterialAsset(src, hasVertexColor: false, modelAsset.Map.Textures);
|
||||
// material.name = src.Name;
|
||||
// modelAsset.Map.Materials.Add(src, material);
|
||||
// modelAsset.Materials.Add(material);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
static private void CreateMeshAsset(VrmLib.Model model, ModelAsset modelAsset)
|
||||
{
|
||||
for (int i = 0; i < model.MeshGroups.Count; ++i)
|
||||
{
|
||||
var src = model.MeshGroups[i];
|
||||
if (src.Meshes.Count == 1)
|
||||
{
|
||||
// submesh 方式
|
||||
var mesh = new UnityEngine.Mesh();
|
||||
mesh.name = src.Name;
|
||||
mesh.LoadMesh(src.Meshes[0], src.Skin);
|
||||
modelAsset.Map.Meshes.Add(src, mesh);
|
||||
modelAsset.Meshes.Add(mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 頂点バッファの連結が必用
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
// static private void CreateMeshAsset(VrmLib.Model model, ModelAsset modelAsset)
|
||||
// {
|
||||
// for (int i = 0; i < model.MeshGroups.Count; ++i)
|
||||
// {
|
||||
// var src = model.MeshGroups[i];
|
||||
// if (src.Meshes.Count == 1)
|
||||
// {
|
||||
// // submesh 方式
|
||||
// var mesh = new UnityEngine.Mesh();
|
||||
// mesh.name = src.Name;
|
||||
// mesh.LoadMesh(src.Meshes[0], src.Skin);
|
||||
// modelAsset.Map.Meshes.Add(src, mesh);
|
||||
// modelAsset.Meshes.Add(mesh);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // 頂点バッファの連結が必用
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public interface IExternalUnityObject
|
||||
{
|
||||
Dictionary<string, T> GetExternalUnityObjects<T>() where T : UnityEngine.Object;
|
||||
void SetExternalUnityObject<T>(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEditor.AssetImporters;
|
||||
#else
|
||||
using UnityEditor.Experimental.AssetImporters;
|
||||
#endif
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class ScriptedImporterExtension
|
||||
{
|
||||
public static void ClearExternalObjects<T>(this ScriptedImporter importer) where T : UnityEngine.Object
|
||||
{
|
||||
foreach (var extarnalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)))
|
||||
{
|
||||
importer.RemoveRemap(extarnalObject.Key);
|
||||
}
|
||||
|
||||
AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
|
||||
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public static void ClearExtarnalObjects(this ScriptedImporter importer)
|
||||
{
|
||||
foreach (var extarnalObject in importer.GetExternalObjectMap())
|
||||
{
|
||||
importer.RemoveRemap(extarnalObject.Key);
|
||||
}
|
||||
|
||||
AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
|
||||
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
private static T GetSubAsset<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
|
||||
{
|
||||
return importer.GetSubAssets<T>(assetPath)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetSubAssets<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
|
||||
{
|
||||
return AssetDatabase
|
||||
.LoadAllAssetsAtPath(assetPath)
|
||||
.Where(x => AssetDatabase.IsSubAsset(x))
|
||||
.Where(x => x is T)
|
||||
.Select(x => x as T);
|
||||
}
|
||||
|
||||
private static void ExtractFromAsset(UnityEngine.Object subAsset, string destinationPath, bool isForceUpdate)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(subAsset);
|
||||
|
||||
var clone = UnityEngine.Object.Instantiate(subAsset);
|
||||
AssetDatabase.CreateAsset(clone, destinationPath);
|
||||
|
||||
var assetImporter = AssetImporter.GetAtPath(assetPath);
|
||||
assetImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(subAsset), clone);
|
||||
|
||||
if (isForceUpdate)
|
||||
{
|
||||
AssetDatabase.WriteImportSettingsIfDirty(assetPath);
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExtractAssets<T>(this ScriptedImporter importer, string dirName, string extension) where T : UnityEngine.Object
|
||||
{
|
||||
if (string.IsNullOrEmpty(importer.assetPath))
|
||||
return;
|
||||
|
||||
var subAssets = importer.GetSubAssets<T>(importer.assetPath);
|
||||
|
||||
var path = string.Format("{0}/{1}.{2}",
|
||||
Path.GetDirectoryName(importer.assetPath),
|
||||
Path.GetFileNameWithoutExtension(importer.assetPath),
|
||||
dirName
|
||||
);
|
||||
|
||||
var info = importer.SafeCreateDirectory(path);
|
||||
|
||||
foreach (var asset in subAssets)
|
||||
{
|
||||
ExtractFromAsset(asset, string.Format("{0}/{1}{2}", path, asset.name, extension), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void ExtractTextures(this ScriptedImporter importer, string dirName, Func<string, VrmLib.Model> CreateModel, Action onComplited = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(importer.assetPath))
|
||||
return;
|
||||
|
||||
var subAssets = importer.GetSubAssets<UnityEngine.Texture2D>(importer.assetPath);
|
||||
|
||||
var path = string.Format("{0}/{1}.{2}",
|
||||
Path.GetDirectoryName(importer.assetPath),
|
||||
Path.GetFileNameWithoutExtension(importer.assetPath),
|
||||
dirName
|
||||
);
|
||||
|
||||
importer.SafeCreateDirectory(path);
|
||||
|
||||
Dictionary<VrmLib.ImageTexture, string> targetPaths = new Dictionary<VrmLib.ImageTexture, string>();
|
||||
|
||||
// Reload Model
|
||||
var model = CreateModel(importer.assetPath);
|
||||
var mimeTypeReg = new System.Text.RegularExpressions.Regex("image/(?<mime>.*)$");
|
||||
int count = 0;
|
||||
foreach (var texture in model.Textures)
|
||||
{
|
||||
var imageTexture = texture as VrmLib.ImageTexture;
|
||||
if (imageTexture == null) continue;
|
||||
|
||||
var mimeType = mimeTypeReg.Match(imageTexture.Image.MimeType);
|
||||
var assetName = !string.IsNullOrEmpty(imageTexture.Name) ? imageTexture.Name : string.Format("{0}_img{1}", model.Root.Name, count);
|
||||
var targetPath = string.Format("{0}/{1}.{2}",
|
||||
path,
|
||||
assetName,
|
||||
mimeType.Groups["mime"].Value);
|
||||
imageTexture.Name = assetName;
|
||||
|
||||
if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.MetallicRoughness
|
||||
|| imageTexture.TextureType == VrmLib.Texture.TextureTypes.Occlusion)
|
||||
{
|
||||
var subAssetTexture = subAssets.Where(x => x.name == imageTexture.Name).FirstOrDefault();
|
||||
File.WriteAllBytes(targetPath, subAssetTexture.EncodeToPNG());
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllBytes(targetPath, imageTexture.Image.Bytes.ToArray());
|
||||
}
|
||||
|
||||
AssetDatabase.ImportAsset(targetPath);
|
||||
targetPaths.Add(imageTexture, targetPath);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
EditorApplication.delayCall += () =>
|
||||
{
|
||||
foreach (var targetPath in targetPaths)
|
||||
{
|
||||
var imageTexture = targetPath.Key;
|
||||
var targetTextureImporter = AssetImporter.GetAtPath(targetPath.Value) as TextureImporter;
|
||||
targetTextureImporter.sRGBTexture = (imageTexture.ColorSpace == VrmLib.Texture.ColorSpaceTypes.Srgb);
|
||||
if (imageTexture.TextureType == VrmLib.Texture.TextureTypes.NormalMap)
|
||||
{
|
||||
targetTextureImporter.textureType = TextureImporterType.NormalMap;
|
||||
}
|
||||
targetTextureImporter.SaveAndReimport();
|
||||
|
||||
var externalObject = AssetDatabase.LoadAssetAtPath(targetPath.Value, typeof(UnityEngine.Texture2D));
|
||||
importer.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), imageTexture.Name), externalObject);
|
||||
}
|
||||
|
||||
//AssetDatabase.WriteImportSettingsIfDirty(assetPath);
|
||||
AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
|
||||
if (onComplited != null)
|
||||
{
|
||||
onComplited();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static DirectoryInfo SafeCreateDirectory(this ScriptedImporter importer, string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Directory.CreateDirectory(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb950c51864585a4688048266e6c3a00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,221 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEditor.AssetImporters;
|
||||
#else
|
||||
using UnityEditor.Experimental.AssetImporters;
|
||||
using UnityEngine;
|
||||
#endif
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
|
||||
[ScriptedImporter(1, "vrm")]
|
||||
public class VrmScriptedImporter : ScriptedImporter, IExternalUnityObject
|
||||
public class VrmScriptedImporter : ScriptedImporter
|
||||
{
|
||||
const string TextureDirName = "Textures";
|
||||
const string MaterialDirName = "Materials";
|
||||
const string MetaDirName = "MetaObjects";
|
||||
const string ExpressionDirName = "Expressions";
|
||||
[SerializeField]
|
||||
public bool MigrateToVrm1 = default;
|
||||
|
||||
public override void OnImportAsset(AssetImportContext ctx)
|
||||
{
|
||||
Debug.Log("OnImportAsset to " + ctx.assetPath);
|
||||
|
||||
try
|
||||
{
|
||||
// Create Vrm Model
|
||||
VrmLib.Model model = VrmLoader.CreateVrmModel(ctx.assetPath);
|
||||
if (model == null)
|
||||
{
|
||||
// maybe VRM-0.X
|
||||
return;
|
||||
}
|
||||
Debug.Log($"VrmLoader.CreateVrmModel: {model}");
|
||||
|
||||
// Build Unity Model
|
||||
var assets = EditorUnityBuilder.ToUnityAsset(model, assetPath, this);
|
||||
ComponentBuilder.Build10(model, assets);
|
||||
|
||||
// Texture
|
||||
var externalTextures = this.GetExternalUnityObjects<UnityEngine.Texture2D>();
|
||||
foreach (var texture in assets.Textures)
|
||||
{
|
||||
if (texture == null)
|
||||
continue;
|
||||
|
||||
if (externalTextures.ContainsValue(texture))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.AddObjectToAsset(texture.name, texture);
|
||||
}
|
||||
}
|
||||
|
||||
// Material
|
||||
var externalMaterials = this.GetExternalUnityObjects<UnityEngine.Material>();
|
||||
foreach (var material in assets.Materials)
|
||||
{
|
||||
if (material == null)
|
||||
continue;
|
||||
|
||||
if (externalMaterials.ContainsValue(material))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.AddObjectToAsset(material.name, material);
|
||||
}
|
||||
}
|
||||
|
||||
// Mesh
|
||||
foreach (var mesh in assets.Meshes)
|
||||
{
|
||||
ctx.AddObjectToAsset(mesh.name, mesh);
|
||||
}
|
||||
|
||||
//// ScriptableObject
|
||||
// avatar
|
||||
ctx.AddObjectToAsset("avatar", assets.HumanoidAvatar);
|
||||
|
||||
// meta
|
||||
{
|
||||
var external = this.GetExternalUnityObjects<UniVRM10.VRM10MetaObject>().FirstOrDefault();
|
||||
if (external.Value != null)
|
||||
{
|
||||
var controller = assets.Root.GetComponent<VRM10Controller>();
|
||||
if (controller != null)
|
||||
{
|
||||
controller.Meta = external.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var meta = assets.ScriptableObjects
|
||||
.FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10MetaObject)) as UniVRM10.VRM10MetaObject;
|
||||
if (meta != null)
|
||||
{
|
||||
meta.name = "meta";
|
||||
ctx.AddObjectToAsset(meta.name, meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expression
|
||||
{
|
||||
var external = this.GetExternalUnityObjects<UniVRM10.VRM10Expression>();
|
||||
if (external.Any())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
var expression = assets.ScriptableObjects
|
||||
.Where(x => x.GetType() == typeof(UniVRM10.VRM10Expression))
|
||||
.Select(x => x as UniVRM10.VRM10Expression);
|
||||
foreach (var clip in expression)
|
||||
{
|
||||
clip.name = clip.ExpressionName;
|
||||
ctx.AddObjectToAsset(clip.ExpressionName, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
var external = this.GetExternalUnityObjects<UniVRM10.VRM10ExpressionAvatar>().FirstOrDefault();
|
||||
if (external.Value != null)
|
||||
{
|
||||
var controller = assets.Root.GetComponent<VRM10Controller>();
|
||||
if (controller != null)
|
||||
{
|
||||
controller.Expression.ExpressionAvatar = external.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var expressionAvatar = assets.ScriptableObjects
|
||||
.FirstOrDefault(x => x.GetType() == typeof(UniVRM10.VRM10ExpressionAvatar)) as UniVRM10.VRM10ExpressionAvatar;
|
||||
if (expressionAvatar != null)
|
||||
{
|
||||
expressionAvatar.name = "expressionAvatar";
|
||||
ctx.AddObjectToAsset(expressionAvatar.name, expressionAvatar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Root
|
||||
ctx.AddObjectToAsset(assets.Root.name, assets.Root);
|
||||
ctx.SetMainObject(assets.Root);
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExtractTextures()
|
||||
{
|
||||
this.ExtractTextures(TextureDirName, (path) => { return VrmLoader.CreateVrmModel(path); });
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public void ExtractMaterials()
|
||||
{
|
||||
this.ExtractAssets<UnityEngine.Material>(MaterialDirName, ".mat");
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public void ExtractMaterialsAndTextures()
|
||||
{
|
||||
this.ExtractTextures(TextureDirName, (path) => { return VrmLoader.CreateVrmModel(path); }, () => { this.ExtractAssets<UnityEngine.Material>(MaterialDirName, ".mat"); });
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public void ExtractMeta()
|
||||
{
|
||||
this.ExtractAssets<UniVRM10.VRM10MetaObject>(MetaDirName, ".asset");
|
||||
var metaObject = this.GetExternalUnityObjects<UniVRM10.VRM10MetaObject>().FirstOrDefault();
|
||||
var metaObjectPath = AssetDatabase.GetAssetPath(metaObject.Value);
|
||||
if (!string.IsNullOrEmpty(metaObjectPath))
|
||||
{
|
||||
EditorUtility.SetDirty(metaObject.Value);
|
||||
AssetDatabase.WriteImportSettingsIfDirty(metaObjectPath);
|
||||
}
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public void ExtractExpressions()
|
||||
{
|
||||
this.ExtractAssets<UniVRM10.VRM10ExpressionAvatar>(ExpressionDirName, ".asset");
|
||||
this.ExtractAssets<UniVRM10.VRM10Expression>(ExpressionDirName, ".asset");
|
||||
|
||||
var expressionAvatar = this.GetExternalUnityObjects<UniVRM10.VRM10ExpressionAvatar>().FirstOrDefault();
|
||||
var expressions = this.GetExternalUnityObjects<UniVRM10.VRM10Expression>();
|
||||
|
||||
expressionAvatar.Value.Clips = expressions.Select(x => x.Value).ToList();
|
||||
var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar.Value);
|
||||
if (!string.IsNullOrEmpty(avatarPath))
|
||||
{
|
||||
EditorUtility.SetDirty(expressionAvatar.Value);
|
||||
AssetDatabase.WriteImportSettingsIfDirty(avatarPath);
|
||||
}
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
|
||||
public Dictionary<string, T> GetExternalUnityObjects<T>() where T : UnityEngine.Object
|
||||
{
|
||||
return this.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)).ToDictionary(x => x.Key.name, x => (T)x.Value);
|
||||
}
|
||||
|
||||
public void SetExternalUnityObject<T>(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object
|
||||
{
|
||||
this.AddRemap(sourceAssetIdentifier, obj);
|
||||
AssetDatabase.WriteImportSettingsIfDirty(this.assetPath);
|
||||
AssetDatabase.ImportAsset(this.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
VrmScriptedImporterImpl.Import(this, ctx, MigrateToVrm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UniGLTF;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEditor.AssetImporters;
|
||||
#else
|
||||
@@ -13,91 +14,140 @@ namespace UniVRM10
|
||||
[CustomEditor(typeof(VrmScriptedImporter))]
|
||||
public class VrmScriptedImporterEditorGUI : ScriptedImporterEditor
|
||||
{
|
||||
// const string TextureDirName = "Textures";
|
||||
// const string MaterialDirName = "Materials";
|
||||
// const string MetaDirName = "MetaObjects";
|
||||
// const string ExpressionDirName = "Expressions";
|
||||
|
||||
private bool _isOpen = true;
|
||||
VrmScriptedImporter m_importer;
|
||||
GltfParser m_parser;
|
||||
VrmLib.Model m_model;
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
m_importer = target as VrmScriptedImporter;
|
||||
m_parser = VrmScriptedImporterImpl.Parse(m_importer.assetPath, m_importer.MigrateToVrm1);
|
||||
if (m_parser == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_model = VrmLoader.CreateVrmModel(m_parser);
|
||||
}
|
||||
|
||||
enum Tabs
|
||||
{
|
||||
Model,
|
||||
Materials,
|
||||
Vrm,
|
||||
}
|
||||
static Tabs s_currentTab;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var importer = target as VrmScriptedImporter;
|
||||
s_currentTab = MeshUtility.TabBar.OnGUI(s_currentTab);
|
||||
GUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.LabelField("Extract settings");
|
||||
switch (s_currentTab)
|
||||
{
|
||||
case Tabs.Model:
|
||||
base.OnInspectorGUI();
|
||||
break;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("Materials And Textures");
|
||||
GUI.enabled = !(importer.GetExternalUnityObjects<UnityEngine.Material>().Any()
|
||||
&& importer.GetExternalUnityObjects<UnityEngine.Texture2D>().Any());
|
||||
if (GUILayout.Button("Extract"))
|
||||
{
|
||||
importer.ExtractMaterialsAndTextures();
|
||||
}
|
||||
GUI.enabled = !GUI.enabled;
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
importer.ClearExternalObjects<UnityEngine.Material>();
|
||||
importer.ClearExternalObjects<UnityEngine.Texture2D>();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
case Tabs.Materials:
|
||||
if (m_parser != null)
|
||||
{
|
||||
EditorMaterial.OnGUIMaterial(m_importer, m_parser, Vrm10MToonMaterialImporter.EnumerateAllTexturesDistinct);
|
||||
}
|
||||
break;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("Meta");
|
||||
GUI.enabled = !importer.GetExternalUnityObjects<UniVRM10.VRM10MetaObject>().Any();
|
||||
if (GUILayout.Button("Extract"))
|
||||
{
|
||||
importer.ExtractMeta();
|
||||
case Tabs.Vrm:
|
||||
break;
|
||||
}
|
||||
GUI.enabled = !GUI.enabled;
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
importer.ClearExternalObjects<UniVRM10.VRM10MetaObject>();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("Expressions");
|
||||
GUI.enabled = !(importer.GetExternalUnityObjects<UniVRM10.VRM10ExpressionAvatar>().Any()
|
||||
&& importer.GetExternalUnityObjects<UniVRM10.VRM10Expression>().Any());
|
||||
if (GUILayout.Button("Extract"))
|
||||
{
|
||||
importer.ExtractExpressions();
|
||||
}
|
||||
GUI.enabled = !GUI.enabled;
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
importer.ClearExternalObjects<UniVRM10.VRM10ExpressionAvatar>();
|
||||
importer.ClearExternalObjects<UniVRM10.VRM10Expression>();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// ObjectMap
|
||||
DrawRemapGUI<UnityEngine.Material>("Material Remap", importer);
|
||||
DrawRemapGUI<UnityEngine.Texture2D>("Texture Remap", importer);
|
||||
DrawRemapGUI<UniVRM10.VRM10MetaObject>("Meta Remap", importer);
|
||||
DrawRemapGUI<UniVRM10.VRM10ExpressionAvatar>("ExpressionAvatar Remap", importer);
|
||||
DrawRemapGUI<UniVRM10.VRM10Expression>("Expression Remap", importer);
|
||||
|
||||
base.OnInspectorGUI();
|
||||
}
|
||||
|
||||
private void DrawRemapGUI<T>(string title, VrmScriptedImporter importer) where T : UnityEngine.Object
|
||||
{
|
||||
EditorGUILayout.Foldout(_isOpen, title);
|
||||
EditorGUI.indentLevel++;
|
||||
var objects = importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T));
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(obj.Key.name);
|
||||
var asset = EditorGUILayout.ObjectField(obj.Value, obj.Key.type, true) as T;
|
||||
if (asset != obj.Value)
|
||||
{
|
||||
importer.SetExternalUnityObject(obj.Key, asset);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
// var importer = target as VrmScriptedImporter;
|
||||
|
||||
// EditorGUILayout.LabelField("Extract settings");
|
||||
|
||||
// EditorGUILayout.BeginHorizontal();
|
||||
// EditorGUILayout.PrefixLabel("Materials And Textures");
|
||||
// GUI.enabled = !(importer.GetExternalUnityObjects<UnityEngine.Material>().Any()
|
||||
// && importer.GetExternalUnityObjects<UnityEngine.Texture2D>().Any());
|
||||
// if (GUILayout.Button("Extract"))
|
||||
// {
|
||||
// importer.ExtractMaterialsAndTextures();
|
||||
// }
|
||||
// GUI.enabled = !GUI.enabled;
|
||||
// if (GUILayout.Button("Clear"))
|
||||
// {
|
||||
// importer.ClearExternalObjects<UnityEngine.Material>();
|
||||
// importer.ClearExternalObjects<UnityEngine.Texture2D>();
|
||||
// }
|
||||
// GUI.enabled = true;
|
||||
// EditorGUILayout.EndHorizontal();
|
||||
|
||||
// EditorGUILayout.BeginHorizontal();
|
||||
// EditorGUILayout.PrefixLabel("Meta");
|
||||
// GUI.enabled = !importer.GetExternalUnityObjects<UniVRM10.VRM10MetaObject>().Any();
|
||||
// if (GUILayout.Button("Extract"))
|
||||
// {
|
||||
// importer.ExtractMeta();
|
||||
// }
|
||||
// GUI.enabled = !GUI.enabled;
|
||||
// if (GUILayout.Button("Clear"))
|
||||
// {
|
||||
// importer.ClearExternalObjects<UniVRM10.VRM10MetaObject>();
|
||||
// }
|
||||
// GUI.enabled = true;
|
||||
// EditorGUILayout.EndHorizontal();
|
||||
|
||||
// EditorGUILayout.BeginHorizontal();
|
||||
// EditorGUILayout.PrefixLabel("Expressions");
|
||||
// GUI.enabled = !(importer.GetExternalUnityObjects<UniVRM10.VRM10ExpressionAvatar>().Any()
|
||||
// && importer.GetExternalUnityObjects<UniVRM10.VRM10Expression>().Any());
|
||||
// if (GUILayout.Button("Extract"))
|
||||
// {
|
||||
// importer.ExtractExpressions();
|
||||
// }
|
||||
// GUI.enabled = !GUI.enabled;
|
||||
// if (GUILayout.Button("Clear"))
|
||||
// {
|
||||
// importer.ClearExternalObjects<UniVRM10.VRM10ExpressionAvatar>();
|
||||
// importer.ClearExternalObjects<UniVRM10.VRM10Expression>();
|
||||
// }
|
||||
// GUI.enabled = true;
|
||||
// EditorGUILayout.EndHorizontal();
|
||||
|
||||
// // ObjectMap
|
||||
// DrawRemapGUI<UnityEngine.Material>("Material Remap", importer);
|
||||
// DrawRemapGUI<UnityEngine.Texture2D>("Texture Remap", importer);
|
||||
// DrawRemapGUI<UniVRM10.VRM10MetaObject>("Meta Remap", importer);
|
||||
// DrawRemapGUI<UniVRM10.VRM10ExpressionAvatar>("ExpressionAvatar Remap", importer);
|
||||
// DrawRemapGUI<UniVRM10.VRM10Expression>("Expression Remap", importer);
|
||||
|
||||
// base.OnInspectorGUI();
|
||||
// }
|
||||
|
||||
// private void DrawRemapGUI<T>(string title, VrmScriptedImporter importer) where T : UnityEngine.Object
|
||||
// {
|
||||
// EditorGUILayout.Foldout(_isOpen, title);
|
||||
// EditorGUI.indentLevel++;
|
||||
// var objects = importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T));
|
||||
// foreach (var obj in objects)
|
||||
// {
|
||||
// EditorGUILayout.BeginHorizontal();
|
||||
// EditorGUILayout.PrefixLabel(obj.Key.name);
|
||||
// var asset = EditorGUILayout.ObjectField(obj.Value, obj.Key.type, true) as T;
|
||||
// if (asset != obj.Value)
|
||||
// {
|
||||
// importer.SetExternalUnityObject(obj.Key, asset);
|
||||
// }
|
||||
// EditorGUILayout.EndHorizontal();
|
||||
// }
|
||||
// EditorGUI.indentLevel--;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
208
Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
Normal file
208
Assets/VRM10/Editor/ScriptedImporter/VrmScriptedImporterImpl.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UniGLTF;
|
||||
using System.IO;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEditor.AssetImporters;
|
||||
#else
|
||||
using UnityEditor.Experimental.AssetImporters;
|
||||
#endif
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class VrmScriptedImporterImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// VRM1 で パースし、失敗したら Migration してから VRM1 でパースする
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="migrateToVrm1"></param>
|
||||
/// <returns></returns>
|
||||
public static GltfParser Parse(string path, bool migrateToVrm1)
|
||||
{
|
||||
//
|
||||
// Parse(parse glb, parser gltf json)
|
||||
//
|
||||
var parser = new GltfParser();
|
||||
parser.ParsePath(path);
|
||||
if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(parser.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
|
||||
{
|
||||
return parser;
|
||||
}
|
||||
|
||||
if (migrateToVrm1)
|
||||
{
|
||||
// try migrateion
|
||||
var migrated = MigrationVrm.Migrate(File.ReadAllBytes(path));
|
||||
parser = new GltfParser();
|
||||
parser.Parse(path, migrated);
|
||||
return parser;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1)
|
||||
{
|
||||
#if VRM_DEVELOP
|
||||
Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
|
||||
#endif
|
||||
|
||||
var parser = Parse(scriptedImporter.assetPath, migrateToVrm1);
|
||||
if (parser == null)
|
||||
{
|
||||
// fail to parse vrm1
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Import(create unity objects)
|
||||
//
|
||||
var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray();
|
||||
|
||||
using (var loader = new RuntimeUnityBuilder(parser, externalObjectMap))
|
||||
{
|
||||
// settings TextureImporters
|
||||
foreach (var textureInfo in Vrm10MToonMaterialImporter.EnumerateAllTexturesDistinct(parser))
|
||||
{
|
||||
TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
|
||||
}
|
||||
|
||||
loader.Load();
|
||||
loader.ShowMeshes();
|
||||
|
||||
loader.TransferOwnership(o =>
|
||||
{
|
||||
context.AddObjectToAsset(o.name, o);
|
||||
if (o is GameObject)
|
||||
{
|
||||
// Root GameObject is main object
|
||||
context.SetMainObject(loader.Root);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// public void ExtractMeta()
|
||||
// {
|
||||
// this.ExtractAssets<UniVRM10.VRM10MetaObject>(MetaDirName, ".asset");
|
||||
// var metaObject = this.GetExternalUnityObjects<UniVRM10.VRM10MetaObject>().FirstOrDefault();
|
||||
// var metaObjectPath = AssetDatabase.GetAssetPath(metaObject.Value);
|
||||
// if (!string.IsNullOrEmpty(metaObjectPath))
|
||||
// {
|
||||
// EditorUtility.SetDirty(metaObject.Value);
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(metaObjectPath);
|
||||
// }
|
||||
// AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
|
||||
// public void ExtractExpressions()
|
||||
// {
|
||||
// this.ExtractAssets<UniVRM10.VRM10ExpressionAvatar>(ExpressionDirName, ".asset");
|
||||
// this.ExtractAssets<UniVRM10.VRM10Expression>(ExpressionDirName, ".asset");
|
||||
|
||||
// var expressionAvatar = this.GetExternalUnityObjects<UniVRM10.VRM10ExpressionAvatar>().FirstOrDefault();
|
||||
// var expressions = this.GetExternalUnityObjects<UniVRM10.VRM10Expression>();
|
||||
|
||||
// expressionAvatar.Value.Clips = expressions.Select(x => x.Value).ToList();
|
||||
// var avatarPath = AssetDatabase.GetAssetPath(expressionAvatar.Value);
|
||||
// if (!string.IsNullOrEmpty(avatarPath))
|
||||
// {
|
||||
// EditorUtility.SetDirty(expressionAvatar.Value);
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(avatarPath);
|
||||
// }
|
||||
|
||||
// AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
|
||||
// public Dictionary<string, T> GetExternalUnityObjects<T>() where T : UnityEngine.Object
|
||||
// {
|
||||
// return this.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)).ToDictionary(x => x.Key.name, x => (T)x.Value);
|
||||
// }
|
||||
|
||||
// public void SetExternalUnityObject<T>(UnityEditor.AssetImporter.SourceAssetIdentifier sourceAssetIdentifier, T obj) where T : UnityEngine.Object
|
||||
// {
|
||||
// this.AddRemap(sourceAssetIdentifier, obj);
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(this.assetPath);
|
||||
// AssetDatabase.ImportAsset(this.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
|
||||
// public static void ClearExternalObjects<T>(this ScriptedImporter importer) where T : UnityEngine.Object
|
||||
// {
|
||||
// foreach (var extarnalObject in importer.GetExternalObjectMap().Where(x => x.Key.type == typeof(T)))
|
||||
// {
|
||||
// importer.RemoveRemap(extarnalObject.Key);
|
||||
// }
|
||||
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
|
||||
// AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
|
||||
// public static void ClearExtarnalObjects(this ScriptedImporter importer)
|
||||
// {
|
||||
// foreach (var extarnalObject in importer.GetExternalObjectMap())
|
||||
// {
|
||||
// importer.RemoveRemap(extarnalObject.Key);
|
||||
// }
|
||||
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(importer.assetPath);
|
||||
// AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
|
||||
// private static T GetSubAsset<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
|
||||
// {
|
||||
// return importer.GetSubAssets<T>(assetPath)
|
||||
// .FirstOrDefault();
|
||||
// }
|
||||
|
||||
// public static IEnumerable<T> GetSubAssets<T>(this ScriptedImporter importer, string assetPath) where T : UnityEngine.Object
|
||||
// {
|
||||
// return AssetDatabase
|
||||
// .LoadAllAssetsAtPath(assetPath)
|
||||
// .Where(x => AssetDatabase.IsSubAsset(x))
|
||||
// .Where(x => x is T)
|
||||
// .Select(x => x as T);
|
||||
// }
|
||||
|
||||
// private static void ExtractFromAsset(UnityEngine.Object subAsset, string destinationPath, bool isForceUpdate)
|
||||
// {
|
||||
// string assetPath = AssetDatabase.GetAssetPath(subAsset);
|
||||
|
||||
// var clone = UnityEngine.Object.Instantiate(subAsset);
|
||||
// AssetDatabase.CreateAsset(clone, destinationPath);
|
||||
|
||||
// var assetImporter = AssetImporter.GetAtPath(assetPath);
|
||||
// assetImporter.AddRemap(new AssetImporter.SourceAssetIdentifier(subAsset), clone);
|
||||
|
||||
// if (isForceUpdate)
|
||||
// {
|
||||
// AssetDatabase.WriteImportSettingsIfDirty(assetPath);
|
||||
// AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static void ExtractAssets<T>(this ScriptedImporter importer, string dirName, string extension) where T : UnityEngine.Object
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(importer.assetPath))
|
||||
// return;
|
||||
|
||||
// var subAssets = importer.GetSubAssets<T>(importer.assetPath);
|
||||
|
||||
// var path = string.Format("{0}/{1}.{2}",
|
||||
// Path.GetDirectoryName(importer.assetPath),
|
||||
// Path.GetFileNameWithoutExtension(importer.assetPath),
|
||||
// dirName
|
||||
// );
|
||||
|
||||
// var info = importer.SafeCreateDirectory(path);
|
||||
|
||||
// foreach (var asset in subAssets)
|
||||
// {
|
||||
// ExtractFromAsset(asset, string.Format("{0}/{1}{2}", path, asset.name, extension), false);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35c90d5d3fa706b4f87a92ce4dc59008
|
||||
guid: f08e514e6a60bd0479ed1c928e8b515e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -6,7 +6,8 @@
|
||||
"MeshUtility",
|
||||
"MeshUtility.Editor",
|
||||
"UniGLTF.Editor",
|
||||
"UniGLTF"
|
||||
"UniGLTF",
|
||||
"VRMShaders"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace UniVRM10
|
||||
{
|
||||
return ("", MessageType.None);
|
||||
});
|
||||
m_reference = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.Reference)), prop =>
|
||||
m_reference = new ValidateProperty(serializedObject.FindProperty(nameof(m_target.References)), prop =>
|
||||
{
|
||||
return ("", MessageType.None);
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace UniVRM10
|
||||
Selection.selectionChanged += Repaint;
|
||||
|
||||
m_tmpMeta = ScriptableObject.CreateInstance<VRM10MetaObject>();
|
||||
m_tmpMeta.Authors = new string[] { "" };
|
||||
m_tmpMeta.Authors = new List<string> { "" };
|
||||
|
||||
m_state = new MeshUtility.ExporterDialogState();
|
||||
m_state.ExportRootChanged += (root) =>
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace UniVRM10
|
||||
/// FreezeAxesで使う。bitマスク
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum AxesMask
|
||||
public enum AxisMask
|
||||
{
|
||||
X = 1,
|
||||
Y = 2,
|
||||
@@ -16,17 +16,17 @@ namespace UniVRM10
|
||||
|
||||
public static class AxesMaskExtensions
|
||||
{
|
||||
public static Vector3 Freeze(this AxesMask mask, Vector3 src)
|
||||
public static Vector3 Freeze(this AxisMask mask, Vector3 src)
|
||||
{
|
||||
if (mask.HasFlag(AxesMask.X))
|
||||
if (mask.HasFlag(AxisMask.X))
|
||||
{
|
||||
src.x = 0;
|
||||
}
|
||||
if (mask.HasFlag(AxesMask.Y))
|
||||
if (mask.HasFlag(AxisMask.Y))
|
||||
{
|
||||
src.y = 0;
|
||||
}
|
||||
if (mask.HasFlag(AxesMask.Z))
|
||||
if (mask.HasFlag(AxisMask.Z))
|
||||
{
|
||||
src.z = 0;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,28 @@
|
||||
using System;
|
||||
using UniGLTF.Extensions.VRMC_constraints;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public enum DestinationCoordinates
|
||||
{
|
||||
World,
|
||||
Local,
|
||||
}
|
||||
|
||||
class ConstraintDestination
|
||||
{
|
||||
readonly Transform m_transform;
|
||||
readonly DestinationCoordinates m_coords;
|
||||
readonly ObjectSpace m_coords;
|
||||
|
||||
readonly TRS m_initial;
|
||||
|
||||
public ConstraintDestination(Transform t, DestinationCoordinates coords)
|
||||
public ConstraintDestination(Transform t, ObjectSpace coords)
|
||||
{
|
||||
m_transform = t;
|
||||
m_coords = coords;
|
||||
|
||||
switch (m_coords)
|
||||
{
|
||||
case DestinationCoordinates.World:
|
||||
m_initial = TRS.GetWorld(t);
|
||||
break;
|
||||
// case ObjectSpace.World:
|
||||
// m_initial = TRS.GetWorld(t);
|
||||
// break;
|
||||
|
||||
case DestinationCoordinates.Local:
|
||||
case ObjectSpace.local:
|
||||
m_initial = TRS.GetLocal(t);
|
||||
break;
|
||||
|
||||
@@ -41,11 +36,11 @@ namespace UniVRM10
|
||||
var value = m_initial.Translation + delta * weight;
|
||||
switch (m_coords)
|
||||
{
|
||||
case DestinationCoordinates.World:
|
||||
m_transform.position = value;
|
||||
break;
|
||||
// case DestinationCoordinates.World:
|
||||
// m_transform.position = value;
|
||||
// break;
|
||||
|
||||
case DestinationCoordinates.Local:
|
||||
case ObjectSpace.local:
|
||||
m_transform.localPosition = value;
|
||||
break;
|
||||
|
||||
@@ -60,11 +55,11 @@ namespace UniVRM10
|
||||
var value = Quaternion.LerpUnclamped(Quaternion.identity, delta, weight) * m_initial.Rotation;
|
||||
switch (m_coords)
|
||||
{
|
||||
case DestinationCoordinates.World:
|
||||
m_transform.rotation = value;
|
||||
break;
|
||||
// case DestinationCoordinates.World:
|
||||
// m_transform.rotation = value;
|
||||
// break;
|
||||
|
||||
case DestinationCoordinates.Local:
|
||||
case ObjectSpace.local:
|
||||
m_transform.localRotation = value;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,33 +1,16 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UniGLTF.Extensions.VRMC_constraints;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public enum SourceCoordinates
|
||||
{
|
||||
/// <summary>
|
||||
/// ワールド座標
|
||||
/// </summary>
|
||||
World,
|
||||
|
||||
/// <summary>
|
||||
/// モデルルート(指定のTransform)ローカル座標
|
||||
/// </summary>
|
||||
Model,
|
||||
|
||||
/// <summary>
|
||||
/// m_transform ローカル座標
|
||||
/// </summary>
|
||||
Local,
|
||||
}
|
||||
|
||||
class ConstraintSource
|
||||
{
|
||||
readonly Transform m_modelRoot;
|
||||
|
||||
readonly Transform m_transform;
|
||||
|
||||
readonly SourceCoordinates m_coords;
|
||||
readonly ObjectSpace m_coords;
|
||||
|
||||
readonly TRS m_initial;
|
||||
|
||||
@@ -37,9 +20,9 @@ namespace UniVRM10
|
||||
{
|
||||
switch (m_coords)
|
||||
{
|
||||
case SourceCoordinates.World: return m_transform.position - m_initial.Translation;
|
||||
case SourceCoordinates.Local: return m_transform.localPosition - m_initial.Translation;
|
||||
case SourceCoordinates.Model: return m_modelRoot.worldToLocalMatrix.MultiplyPoint(m_transform.position) - m_initial.Translation;
|
||||
// case ObjectSpace.World: return m_transform.position - m_initial.Translation;
|
||||
case ObjectSpace.local: return m_transform.localPosition - m_initial.Translation;
|
||||
case ObjectSpace.model: return m_modelRoot.worldToLocalMatrix.MultiplyPoint(m_transform.position) - m_initial.Translation;
|
||||
default: throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -52,30 +35,30 @@ namespace UniVRM10
|
||||
switch (m_coords)
|
||||
{
|
||||
// 右からかけるか、左からかけるか、それが問題なのだ
|
||||
case SourceCoordinates.World: return m_transform.rotation * Quaternion.Inverse(m_initial.Rotation);
|
||||
case SourceCoordinates.Local: return m_transform.localRotation * Quaternion.Inverse(m_initial.Rotation);
|
||||
case SourceCoordinates.Model: return m_transform.rotation * Quaternion.Inverse(m_modelRoot.rotation) * Quaternion.Inverse(m_initial.Rotation);
|
||||
// case SourceCoordinates.World: return m_transform.rotation * Quaternion.Inverse(m_initial.Rotation);
|
||||
case ObjectSpace.local: return m_transform.localRotation * Quaternion.Inverse(m_initial.Rotation);
|
||||
case ObjectSpace.model: return m_transform.rotation * Quaternion.Inverse(m_modelRoot.rotation) * Quaternion.Inverse(m_initial.Rotation);
|
||||
default: throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConstraintSource(Transform t, SourceCoordinates coords, Transform modelRoot = null)
|
||||
public ConstraintSource(Transform t, ObjectSpace coords, Transform modelRoot = null)
|
||||
{
|
||||
m_transform = t;
|
||||
m_coords = coords;
|
||||
|
||||
switch (coords)
|
||||
{
|
||||
case SourceCoordinates.World:
|
||||
m_initial = TRS.GetWorld(t);
|
||||
break;
|
||||
// case SourceCoordinates.World:
|
||||
// m_initial = TRS.GetWorld(t);
|
||||
// break;
|
||||
|
||||
case SourceCoordinates.Local:
|
||||
case ObjectSpace.local:
|
||||
m_initial = TRS.GetLocal(t);
|
||||
break;
|
||||
|
||||
case SourceCoordinates.Model:
|
||||
case ObjectSpace.model:
|
||||
{
|
||||
var world = TRS.GetWorld(t);
|
||||
m_modelRoot = modelRoot;
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace UniVRM10
|
||||
///
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class VRMAimConstraint : VRMConstraint
|
||||
public class VRM10AimConstraint : VRM10Constraint
|
||||
{
|
||||
[SerializeField]
|
||||
Transform Source = default;
|
||||
public Transform Source = default;
|
||||
|
||||
// [SerializeField]
|
||||
// [Range(0, 10.0f)]
|
||||
@@ -24,12 +24,13 @@ namespace UniVRM10
|
||||
/// Forward
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
Vector3 AimVector = Vector3.forward;
|
||||
public Vector3 AimVector = Vector3.forward;
|
||||
|
||||
[SerializeField]
|
||||
Vector3 UpVector = Vector3.up;
|
||||
public Vector3 UpVector = Vector3.up;
|
||||
|
||||
Vector3 RightVector;
|
||||
[SerializeField]
|
||||
public Vector3 RightVector;
|
||||
|
||||
Quaternion m_selfInitial;
|
||||
Matrix4x4 m_coords;
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1e8c3a00191fbd4db98fb47ddb80e8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,7 +2,7 @@ using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public abstract class VRMConstraint : MonoBehaviour
|
||||
public abstract class VRM10Constraint : MonoBehaviour
|
||||
{
|
||||
public virtual void Process()
|
||||
{
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ded8c4db12c688b46814cf0bf925cacf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UniGLTF.Extensions.VRMC_constraints;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
@@ -6,26 +7,26 @@ namespace UniVRM10
|
||||
/// 対象の初期位置と現在位置の差分(delta)を、自身の初期位置に対してWeightを乗算して加算する。
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class VRMPositionConstraint : VRMConstraint
|
||||
public class VRM10PositionConstraint : VRM10Constraint
|
||||
{
|
||||
[SerializeField]
|
||||
Transform Source = default;
|
||||
public Transform Source = default;
|
||||
|
||||
[SerializeField]
|
||||
SourceCoordinates SourceCoordinate = default;
|
||||
public ObjectSpace SourceCoordinate = default;
|
||||
|
||||
[SerializeField]
|
||||
DestinationCoordinates DestinationCoordinate = default;
|
||||
public ObjectSpace DestinationCoordinate = default;
|
||||
|
||||
[SerializeField]
|
||||
AxesMask FreezeAxes = default;
|
||||
public AxisMask FreezeAxes = default;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0, 10.0f)]
|
||||
float Weight = 1.0f;
|
||||
public float Weight = 1.0f;
|
||||
|
||||
[SerializeField]
|
||||
Transform ModelRoot = default;
|
||||
public Transform ModelRoot = default;
|
||||
|
||||
ConstraintSource m_src;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fec0847a81b2124c9f67575d247b1f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UniGLTF.Extensions.VRMC_constraints;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -7,26 +8,26 @@ namespace UniVRM10
|
||||
/// 対象の初期回転と現在回転の差分(delta)を、自身の初期回転と自身の初期回転にdeltaを乗算したものに対してWeightでSlerpする。
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class VRMRotationConstraint : VRMConstraint
|
||||
public class VRM10RotationConstraint : VRM10Constraint
|
||||
{
|
||||
[SerializeField]
|
||||
Transform Source = default;
|
||||
public Transform Source = default;
|
||||
|
||||
[SerializeField]
|
||||
SourceCoordinates SourceCoordinate = default;
|
||||
public ObjectSpace SourceCoordinate = default;
|
||||
|
||||
[SerializeField]
|
||||
DestinationCoordinates DestinationCoordinate = default;
|
||||
public ObjectSpace DestinationCoordinate = default;
|
||||
|
||||
[SerializeField]
|
||||
AxesMask FreezeAxes = default;
|
||||
public AxisMask FreezeAxes = default;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0, 10.0f)]
|
||||
float Weight = 1.0f;
|
||||
public float Weight = 1.0f;
|
||||
|
||||
[SerializeField]
|
||||
Transform ModelRoot = default;
|
||||
public Transform ModelRoot = default;
|
||||
|
||||
ConstraintSource m_src;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a07fbecedce41b4396f286fd7634e1d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8f13bc2bb7b6734e92bba2b204e2e49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e017e9a63d31c4e4cbcc905a0caf0605
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f104dcf447611a4ca99f4ac41e806e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7e95091802973e488fdcc4b3840cdc5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UnityEngine;
|
||||
using VrmLib;
|
||||
|
||||
@@ -88,11 +89,11 @@ namespace UniVRM10
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ExpressionOverrideType.None:
|
||||
case ExpressionOverrideType.none:
|
||||
return 0f;
|
||||
case ExpressionOverrideType.Block:
|
||||
case ExpressionOverrideType.block:
|
||||
return weight > 0f ? 1f : 0f;
|
||||
case ExpressionOverrideType.Blend:
|
||||
case ExpressionOverrideType.blend:
|
||||
return weight;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(type), type, null);
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace UniVRM10
|
||||
/// <summary>
|
||||
/// Enum.ToString() のGC回避用キャッシュ
|
||||
/// </summary>
|
||||
private static readonly Dictionary<VrmLib.ExpressionPreset, string> PresetNameDictionary =
|
||||
new Dictionary<VrmLib.ExpressionPreset, string>();
|
||||
private static readonly Dictionary<UniGLTF.Extensions.VRMC_vrm.ExpressionPreset, string> PresetNameDictionary =
|
||||
new Dictionary<UniGLTF.Extensions.VRMC_vrm.ExpressionPreset, string>();
|
||||
|
||||
/// <summary>
|
||||
/// ExpressionPreset と同名の名前を持つ独自に追加した Expression を区別するための prefix
|
||||
@@ -20,7 +20,7 @@ namespace UniVRM10
|
||||
/// <summary>
|
||||
/// Preset of this ExpressionKey.
|
||||
/// </summary>
|
||||
public readonly VrmLib.ExpressionPreset Preset;
|
||||
public readonly UniGLTF.Extensions.VRMC_vrm.ExpressionPreset Preset;
|
||||
|
||||
/// <summary>
|
||||
/// Custom Name of this ExpressionKey.
|
||||
@@ -39,9 +39,9 @@ namespace UniVRM10
|
||||
{
|
||||
switch (Preset)
|
||||
{
|
||||
case VrmLib.ExpressionPreset.Blink:
|
||||
case VrmLib.ExpressionPreset.BlinkLeft:
|
||||
case VrmLib.ExpressionPreset.BlinkRight:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blink:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blinkLeft:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.blinkRight:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -54,10 +54,10 @@ namespace UniVRM10
|
||||
{
|
||||
switch (Preset)
|
||||
{
|
||||
case VrmLib.ExpressionPreset.LookUp:
|
||||
case VrmLib.ExpressionPreset.LookDown:
|
||||
case VrmLib.ExpressionPreset.LookLeft:
|
||||
case VrmLib.ExpressionPreset.LookRight:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.lookUp:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.lookDown:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.lookLeft:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.lookRight:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -70,11 +70,11 @@ namespace UniVRM10
|
||||
{
|
||||
switch (Preset)
|
||||
{
|
||||
case VrmLib.ExpressionPreset.Aa:
|
||||
case VrmLib.ExpressionPreset.Ih:
|
||||
case VrmLib.ExpressionPreset.Ou:
|
||||
case VrmLib.ExpressionPreset.Ee:
|
||||
case VrmLib.ExpressionPreset.Oh:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.aa:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ih:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ou:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.ee:
|
||||
case UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.oh:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -83,11 +83,11 @@ namespace UniVRM10
|
||||
|
||||
public bool IsProcedual => IsBlink || IsLookAt || IsMouth;
|
||||
|
||||
public ExpressionKey(VrmLib.ExpressionPreset preset, string customName = null)
|
||||
public ExpressionKey(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset, string customName = null)
|
||||
{
|
||||
Preset = preset;
|
||||
|
||||
if (Preset != VrmLib.ExpressionPreset.Custom)
|
||||
if (Preset != UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
|
||||
{
|
||||
if (PresetNameDictionary.ContainsKey((Preset)))
|
||||
{
|
||||
@@ -103,7 +103,7 @@ namespace UniVRM10
|
||||
{
|
||||
if (string.IsNullOrEmpty(customName))
|
||||
{
|
||||
throw new ArgumentException("name is required for VrmLib.ExpressionPreset.Custom");
|
||||
throw new ArgumentException("name is required for UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.Custom");
|
||||
}
|
||||
|
||||
_id = $"{UnknownPresetPrefix}{customName}";
|
||||
@@ -113,10 +113,10 @@ namespace UniVRM10
|
||||
|
||||
public static ExpressionKey CreateCustom(String key)
|
||||
{
|
||||
return new ExpressionKey(VrmLib.ExpressionPreset.Custom, key);
|
||||
return new ExpressionKey(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom, key);
|
||||
}
|
||||
|
||||
public static ExpressionKey CreateFromPreset(VrmLib.ExpressionPreset preset)
|
||||
public static ExpressionKey CreateFromPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset)
|
||||
{
|
||||
return new ExpressionKey(preset);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace UniVRM10
|
||||
public struct MaterialColorBinding : IEquatable<MaterialColorBinding>
|
||||
{
|
||||
public String MaterialName;
|
||||
public VrmLib.MaterialBindType BindType;
|
||||
public UniGLTF.Extensions.VRMC_vrm.MaterialColorType BindType;
|
||||
public Vector4 TargetValue;
|
||||
|
||||
public bool Equals(MaterialColorBinding other)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
@@ -9,6 +10,40 @@ namespace UniVRM10
|
||||
///
|
||||
internal sealed class MaterialValueBindingMerger
|
||||
{
|
||||
public const string UV_PROPERTY = "_MainTex_ST";
|
||||
public const string COLOR_PROPERTY = "_Color";
|
||||
public const string EMISSION_COLOR_PROPERTY = "_EmissionColor";
|
||||
public const string RIM_COLOR_PROPERTY = "_RimColor";
|
||||
public const string OUTLINE_COLOR_PROPERTY = "_OutlineColor";
|
||||
public const string SHADE_COLOR_PROPERTY = "_ShadeColor";
|
||||
|
||||
public static string GetProperty(MaterialColorType bindType)
|
||||
{
|
||||
switch (bindType)
|
||||
{
|
||||
// case MaterialBindType.UvOffset:
|
||||
// case MaterialBindType.UvScale:
|
||||
// return UV_PROPERTY;
|
||||
|
||||
case MaterialColorType.color:
|
||||
return COLOR_PROPERTY;
|
||||
|
||||
case MaterialColorType.emissionColor:
|
||||
return EMISSION_COLOR_PROPERTY;
|
||||
|
||||
case MaterialColorType.shadeColor:
|
||||
return SHADE_COLOR_PROPERTY;
|
||||
|
||||
case MaterialColorType.rimColor:
|
||||
return RIM_COLOR_PROPERTY;
|
||||
|
||||
case MaterialColorType.outlineColor:
|
||||
return OUTLINE_COLOR_PROPERTY;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#region MaterialMap
|
||||
/// <summary>
|
||||
/// MaterialValueBinding の対象になるマテリアルの情報を記録する
|
||||
@@ -44,7 +79,7 @@ namespace UniVRM10
|
||||
item = new PreviewMaterialItem(material);
|
||||
m_materialMap.Add(binding.MaterialName, item);
|
||||
}
|
||||
var propName = VrmLib.MaterialBindTypeExtensions.GetProperty(binding.BindType);
|
||||
var propName = GetProperty(binding.BindType);
|
||||
item.PropMap.Add(binding.BindType, new PropItem
|
||||
{
|
||||
Name = propName,
|
||||
@@ -179,7 +214,7 @@ namespace UniVRM10
|
||||
return new MaterialTarget
|
||||
{
|
||||
MaterialName = binding.MaterialName,
|
||||
ValueName = VrmLib.MaterialBindTypeExtensions.GetProperty(binding.BindType),
|
||||
ValueName = GetProperty(binding.BindType),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@@ -57,7 +58,7 @@ namespace UniVRM10
|
||||
Material = material;
|
||||
}
|
||||
|
||||
public Dictionary<VrmLib.MaterialBindType, PropItem> PropMap = new Dictionary<VrmLib.MaterialBindType, PropItem>();
|
||||
public Dictionary<UniGLTF.Extensions.VRMC_vrm.MaterialColorType, PropItem> PropMap = new Dictionary<UniGLTF.Extensions.VRMC_vrm.MaterialColorType, PropItem>();
|
||||
|
||||
public string[] PropNames
|
||||
{
|
||||
@@ -74,6 +75,35 @@ namespace UniVRM10
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public const string UV_PROPERTY = "_MainTex_ST";
|
||||
public const string COLOR_PROPERTY = "_Color";
|
||||
public const string EMISSION_COLOR_PROPERTY = "_EmissionColor";
|
||||
public const string RIM_COLOR_PROPERTY = "_RimColor";
|
||||
public const string OUTLINE_COLOR_PROPERTY = "_OutlineColor";
|
||||
public const string SHADE_COLOR_PROPERTY = "_ShadeColor";
|
||||
public static MaterialColorType GetBindType(string property)
|
||||
{
|
||||
switch (property)
|
||||
{
|
||||
case COLOR_PROPERTY:
|
||||
return MaterialColorType.color;
|
||||
|
||||
case EMISSION_COLOR_PROPERTY:
|
||||
return MaterialColorType.emissionColor;
|
||||
|
||||
case RIM_COLOR_PROPERTY:
|
||||
return MaterialColorType.rimColor;
|
||||
|
||||
case SHADE_COLOR_PROPERTY:
|
||||
return MaterialColorType.shadeColor;
|
||||
|
||||
case OUTLINE_COLOR_PROPERTY:
|
||||
return MaterialColorType.outlineColor;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static PreviewMaterialItem CreateForPreview(Material material)
|
||||
{
|
||||
var item = new PreviewMaterialItem(material);
|
||||
@@ -89,7 +119,7 @@ namespace UniVRM10
|
||||
case ShaderUtil.ShaderPropertyType.Color:
|
||||
// 色
|
||||
{
|
||||
var bindType = VrmLib.MaterialBindTypeExtensions.GetBindType(name);
|
||||
var bindType = GetBindType(name);
|
||||
item.PropMap.Add(bindType, new PropItem
|
||||
{
|
||||
Name = name,
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace UniVRM10
|
||||
/// ExpressionPreset を識別する。 Unknown の場合は、 ExpressionName で識別する
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public VrmLib.ExpressionPreset Preset;
|
||||
public UniGLTF.Extensions.VRMC_vrm.ExpressionPreset Preset;
|
||||
|
||||
/// <summary>
|
||||
/// 対象メッシュの Expression を操作する
|
||||
@@ -83,19 +83,19 @@ namespace UniVRM10
|
||||
/// この Expression と Blink(Blink, BlinkLeft, BlinkRight) が同時に有効な場合、Blink の Weight を 0 にする
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public VrmLib.ExpressionOverrideType OverrideBlink;
|
||||
public UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType OverrideBlink;
|
||||
|
||||
/// <summary>
|
||||
/// この Expression と LookAt(LookUp, LookDown, LookLeft, LookRight) が同時に有効な場合、LookAt の Weight を 0 にする
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public VrmLib.ExpressionOverrideType OverrideLookAt;
|
||||
public UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType OverrideLookAt;
|
||||
|
||||
/// <summary>
|
||||
/// この Expression と Mouth(Aa, Ih, Ou, Ee, Oh) が同時に有効な場合、Mouth の Weight を 0 にする
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public VrmLib.ExpressionOverrideType OverrideMouth;
|
||||
public UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType OverrideMouth;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@@ -104,7 +104,7 @@ namespace UniVRM10
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
if (Preset == VrmLib.ExpressionPreset.Custom)
|
||||
if (Preset == UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ExpressionName))
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace UniVRM10
|
||||
[CreateAssetMenu(menuName = "VRM10/ExpressionAvatar")]
|
||||
public sealed class VRM10ExpressionAvatar : ScriptableObject
|
||||
{
|
||||
public const string ExtractKey = ".ExpressionAvatar";
|
||||
|
||||
[SerializeField]
|
||||
public List<VRM10Expression> Clips = new List<VRM10Expression>();
|
||||
|
||||
@@ -79,15 +81,15 @@ namespace UniVRM10
|
||||
/// </summary>
|
||||
public void CreateDefaultPreset()
|
||||
{
|
||||
foreach (var preset in ((VrmLib.ExpressionPreset[])Enum.GetValues(typeof(VrmLib.ExpressionPreset)))
|
||||
.Where(x => x != VrmLib.ExpressionPreset.Custom)
|
||||
foreach (var preset in ((UniGLTF.Extensions.VRMC_vrm.ExpressionPreset[])Enum.GetValues(typeof(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset)))
|
||||
.Where(x => x != UniGLTF.Extensions.VRMC_vrm.ExpressionPreset.custom)
|
||||
)
|
||||
{
|
||||
CreateDefaultPreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDefaultPreset(VrmLib.ExpressionPreset preset)
|
||||
void CreateDefaultPreset(UniGLTF.Extensions.VRMC_vrm.ExpressionPreset preset)
|
||||
{
|
||||
var clip = GetClip(new ExpressionKey(preset));
|
||||
if (clip != null) return;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace UniVRM10
|
||||
public struct RendererFirstPersonFlags
|
||||
{
|
||||
public Renderer Renderer;
|
||||
public VrmLib.FirstPersonMeshType FirstPersonFlag;
|
||||
public UniGLTF.Extensions.VRMC_vrm.FirstPersonType FirstPersonFlag;
|
||||
public Mesh SharedMesh
|
||||
{
|
||||
get
|
||||
|
||||
@@ -31,20 +31,6 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply(VrmLib.LookAtRangeMap map)
|
||||
{
|
||||
CurveXRangeDegree = map.InputMaxValue;
|
||||
CurveYRangeDegree = map.OutputScaling;
|
||||
}
|
||||
|
||||
IEnumerable<Keyframe> ToKeys(float[] values)
|
||||
{
|
||||
for (int i = 0; i < values.Length; i += 4)
|
||||
{
|
||||
yield return new Keyframe(values[i], values[i + 1], values[i + 2], values[i + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
public float Map(float src)
|
||||
{
|
||||
if (src < 0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UnityEngine;
|
||||
using VrmLib;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
@@ -10,12 +10,12 @@ namespace UniVRM10
|
||||
private readonly CurveMapper _horizontalInner;
|
||||
private readonly CurveMapper _verticalDown;
|
||||
private readonly CurveMapper _verticalUp;
|
||||
|
||||
private readonly ExpressionKey _lookRightKey = ExpressionKey.CreateFromPreset(ExpressionPreset.LookRight);
|
||||
private readonly ExpressionKey _lookLeftKey = ExpressionKey.CreateFromPreset(ExpressionPreset.LookLeft);
|
||||
private readonly ExpressionKey _lookUpKey = ExpressionKey.CreateFromPreset(ExpressionPreset.LookUp);
|
||||
private readonly ExpressionKey _lookDownKey = ExpressionKey.CreateFromPreset(ExpressionPreset.LookDown);
|
||||
|
||||
|
||||
private readonly ExpressionKey _lookRightKey = ExpressionKey.CreateFromPreset(ExpressionPreset.lookRight);
|
||||
private readonly ExpressionKey _lookLeftKey = ExpressionKey.CreateFromPreset(ExpressionPreset.lookLeft);
|
||||
private readonly ExpressionKey _lookUpKey = ExpressionKey.CreateFromPreset(ExpressionPreset.lookUp);
|
||||
private readonly ExpressionKey _lookDownKey = ExpressionKey.CreateFromPreset(ExpressionPreset.lookDown);
|
||||
|
||||
public LookAtEyeDirectionApplicableToExpression(
|
||||
CurveMapper horizontalOuter, CurveMapper horizontalInner, CurveMapper verticalDown, CurveMapper verticalUp)
|
||||
{
|
||||
@@ -29,7 +29,7 @@ namespace UniVRM10
|
||||
{
|
||||
var yaw = eyeDirection.LeftYaw;
|
||||
var pitch = eyeDirection.LeftPitch;
|
||||
|
||||
|
||||
if (yaw < 0)
|
||||
{
|
||||
// Left
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace UniVRM10
|
||||
[CreateAssetMenu(menuName = "VRM10/MetaObject")]
|
||||
public class VRM10MetaObject : ScriptableObject
|
||||
{
|
||||
public const string ExtractKey = ".Meta";
|
||||
|
||||
[SerializeField]
|
||||
public string ExporterVersion;
|
||||
|
||||
@@ -24,13 +26,13 @@ namespace UniVRM10
|
||||
public string CopyrightInformation;
|
||||
|
||||
[SerializeField]
|
||||
public string[] Authors;
|
||||
public List<string> Authors = new List<string>();
|
||||
|
||||
[SerializeField]
|
||||
public string ContactInformation;
|
||||
|
||||
[SerializeField]
|
||||
public string Reference;
|
||||
public List<string> References = new List<string>();
|
||||
|
||||
[SerializeField]
|
||||
public Texture2D Thumbnail;
|
||||
@@ -38,7 +40,7 @@ namespace UniVRM10
|
||||
|
||||
#region AvatarPermission
|
||||
[SerializeField, Tooltip("A person who can perform with this avatar")]
|
||||
public VrmLib.AvatarUsageType AllowedUser;
|
||||
public UniGLTF.Extensions.VRMC_vrm.AvatarPermissionType AllowedUser;
|
||||
|
||||
[SerializeField, Tooltip("Violent acts using this avatar")]
|
||||
public bool ViolentUsage;
|
||||
@@ -47,7 +49,7 @@ namespace UniVRM10
|
||||
public bool SexualUsage;
|
||||
|
||||
[SerializeField, Tooltip("For commercial use")]
|
||||
public VrmLib.CommercialUsageType CommercialUsage;
|
||||
public UniGLTF.Extensions.VRMC_vrm.CommercialUsageType CommercialUsage;
|
||||
|
||||
[SerializeField]
|
||||
public bool GameUsage;
|
||||
@@ -61,13 +63,13 @@ namespace UniVRM10
|
||||
|
||||
#region Distribution License
|
||||
[SerializeField]
|
||||
public VrmLib.CreditNotationType CreditNotation;
|
||||
public UniGLTF.Extensions.VRMC_vrm.CreditNotationType CreditNotation;
|
||||
|
||||
[SerializeField]
|
||||
public bool Redistribution;
|
||||
|
||||
[SerializeField]
|
||||
public VrmLib.ModificationLicenseType ModificationLicense;
|
||||
public UniGLTF.Extensions.VRMC_vrm.ModificationType ModificationLicense;
|
||||
|
||||
[SerializeField]
|
||||
public string OtherLicenseUrl;
|
||||
@@ -80,7 +82,7 @@ namespace UniVRM10
|
||||
yield return Validation.Error("Require Name. ");
|
||||
}
|
||||
|
||||
if (Authors == null || Authors.Length == 0)
|
||||
if (Authors == null || Authors.Count == 0)
|
||||
{
|
||||
yield return Validation.Error("Require at leaset one Author.");
|
||||
}
|
||||
@@ -99,14 +101,14 @@ namespace UniVRM10
|
||||
dst.CopyrightInformation = CopyrightInformation;
|
||||
if (Authors != null)
|
||||
{
|
||||
dst.Authors = Authors.Select(x => x).ToArray();
|
||||
dst.Authors = Authors.Select(x => x).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.Authors = new string[] { };
|
||||
dst.Authors = new List<string>();
|
||||
}
|
||||
dst.ContactInformation = ContactInformation;
|
||||
dst.Reference = Reference;
|
||||
dst.References = References;
|
||||
dst.Thumbnail = Thumbnail;
|
||||
dst.AllowedUser = AllowedUser;
|
||||
dst.ViolentUsage = ViolentUsage;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace UniVRM10
|
||||
public class VRM10SpringBone
|
||||
{
|
||||
[SerializeField]
|
||||
public string m_comment;
|
||||
public string Comment;
|
||||
|
||||
[SerializeField]
|
||||
public List<VRM10SpringJoint> Joints = new List<VRM10SpringJoint>();
|
||||
|
||||
@@ -47,27 +47,15 @@ namespace UniVRM10
|
||||
[SerializeField]
|
||||
public VRM10SpringBoneManager SpringBone = new VRM10SpringBoneManager();
|
||||
|
||||
[SerializeField]
|
||||
public ModelAsset ModelAsset;
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (Expression != null)
|
||||
{
|
||||
Expression.Restore();
|
||||
}
|
||||
|
||||
if (ModelAsset != null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
ModelAsset.DisposeEditor();
|
||||
#else
|
||||
ModelAsset.Dispose();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
VRMConstraint[] m_constraints;
|
||||
VRM10Constraint[] m_constraints;
|
||||
|
||||
Transform m_head;
|
||||
public Transform Head
|
||||
@@ -103,7 +91,7 @@ namespace UniVRM10
|
||||
{
|
||||
var animator = GetComponent<Animator>();
|
||||
if (animator == null) return;
|
||||
|
||||
|
||||
m_head = animator.GetBoneTransform(HumanBodyBones.Head);
|
||||
LookAt.Setup(animator, m_head);
|
||||
Expression.Setup(transform, LookAt, LookAt.EyeDirectionApplicable);
|
||||
@@ -125,7 +113,7 @@ namespace UniVRM10
|
||||
//
|
||||
if (m_constraints == null)
|
||||
{
|
||||
m_constraints = GetComponentsInChildren<VRMConstraint>();
|
||||
m_constraints = GetComponentsInChildren<VRM10Constraint>();
|
||||
}
|
||||
foreach (var constraint in m_constraints)
|
||||
{
|
||||
@@ -152,7 +140,7 @@ namespace UniVRM10
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Controller.UpdateType == VRM10ControllerImpl.UpdateTypes.Update)
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace UniVRM10
|
||||
public sealed class VRM10ControllerExpression
|
||||
{
|
||||
public static IExpressionValidatorFactory ExpressionValidatorFactory = new DefaultExpressionValidator.Factory();
|
||||
|
||||
|
||||
[SerializeField]
|
||||
public VRM10ExpressionAvatar ExpressionAvatar;
|
||||
|
||||
@@ -30,17 +30,19 @@ namespace UniVRM10
|
||||
public float BlinkOverrideRate { get; private set; }
|
||||
public float LookAtOverrideRate { get; private set; }
|
||||
public float MouthOverrideRate { get; private set; }
|
||||
|
||||
|
||||
internal void Setup(Transform transform, ILookAtEyeDirectionProvider eyeDirectionProvider, ILookAtEyeDirectionApplicable eyeDirectionApplicable)
|
||||
{
|
||||
if (ExpressionAvatar == null)
|
||||
{
|
||||
Debug.LogError($"{nameof(VRM10ControllerExpression)}.{nameof(ExpressionAvatar)} is null.");
|
||||
#if VRM_DEVELOP
|
||||
Debug.LogWarning($"{nameof(VRM10ControllerExpression)}.{nameof(ExpressionAvatar)} is null.");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Restore();
|
||||
|
||||
|
||||
_merger = new ExpressionMerger(ExpressionAvatar.Clips, transform);
|
||||
_keys = ExpressionAvatar.Clips.Select(ExpressionKey.CreateFromClip).ToList();
|
||||
var oldInputWeights = _inputWeights;
|
||||
@@ -55,12 +57,12 @@ namespace UniVRM10
|
||||
_eyeDirectionProvider = eyeDirectionProvider;
|
||||
_eyeDirectionApplicable = eyeDirectionApplicable;
|
||||
}
|
||||
|
||||
|
||||
internal void Restore()
|
||||
{
|
||||
_merger?.RestoreMaterialInitialValues();
|
||||
_merger = null;
|
||||
|
||||
|
||||
_eyeDirectionApplicable?.Restore();
|
||||
_eyeDirectionApplicable = null;
|
||||
}
|
||||
@@ -119,18 +121,18 @@ namespace UniVRM10
|
||||
{
|
||||
// 1. Get eye direction from provider.
|
||||
_inputEyeDirection = _eyeDirectionProvider?.EyeDirection ?? default;
|
||||
|
||||
|
||||
// 2. Validate user input, and Output as actual weights.
|
||||
_validator.Validate(_inputWeights, _actualWeights,
|
||||
_inputEyeDirection, out _actualEyeDirection,
|
||||
out var blink, out var lookAt, out var mouth);
|
||||
|
||||
|
||||
// 3. Set eye direction expression weights or any other side-effects (ex. eye bone).
|
||||
_eyeDirectionApplicable?.Apply(_actualEyeDirection, _actualWeights);
|
||||
|
||||
// 4. Set actual weights to raw blendshapes.
|
||||
_merger.SetValues(_actualWeights);
|
||||
|
||||
|
||||
BlinkOverrideRate = blink;
|
||||
LookAtOverrideRate = lookAt;
|
||||
MouthOverrideRate = mouth;
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace UniVRM10
|
||||
{
|
||||
switch (x.FirstPersonFlag)
|
||||
{
|
||||
case VrmLib.FirstPersonMeshType.Auto:
|
||||
case UniGLTF.Extensions.VRMC_vrm.FirstPersonType.auto:
|
||||
{
|
||||
if (x.Renderer is SkinnedMeshRenderer smr)
|
||||
{
|
||||
@@ -131,17 +131,17 @@ namespace UniVRM10
|
||||
}
|
||||
break;
|
||||
|
||||
case VrmLib.FirstPersonMeshType.FirstPersonOnly:
|
||||
case UniGLTF.Extensions.VRMC_vrm.FirstPersonType.firstPersonOnly:
|
||||
// 1人称のカメラでだけ描画されるようにする
|
||||
x.Renderer.gameObject.layer = FIRSTPERSON_ONLY_LAYER;
|
||||
break;
|
||||
|
||||
case VrmLib.FirstPersonMeshType.ThirdPersonOnly:
|
||||
case UniGLTF.Extensions.VRMC_vrm.FirstPersonType.thirdPersonOnly:
|
||||
// 3人称のカメラでだけ描画されるようにする
|
||||
x.Renderer.gameObject.layer = THIRDPERSON_ONLY_LAYER;
|
||||
break;
|
||||
|
||||
case VrmLib.FirstPersonMeshType.Both:
|
||||
case UniGLTF.Extensions.VRMC_vrm.FirstPersonType.both:
|
||||
// 特に何もしない。すべてのカメラで描画される
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using VrmLib;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@@ -11,14 +10,6 @@ namespace UniVRM10
|
||||
[Serializable]
|
||||
public class VRM10ControllerLookAt : ILookAtEyeDirectionProvider
|
||||
{
|
||||
public enum LookAtTypes
|
||||
{
|
||||
// Gaze control by bone (leftEye, rightEye)
|
||||
Bone,
|
||||
// Gaze control by blend shape (lookUp, lookDown, lookLeft, lookRight)
|
||||
Expression,
|
||||
}
|
||||
|
||||
public enum LookAtTargetTypes
|
||||
{
|
||||
CalcYawPitchToGaze,
|
||||
@@ -32,7 +23,7 @@ namespace UniVRM10
|
||||
public Vector3 OffsetFromHead = new Vector3(0, 0.06f, 0);
|
||||
|
||||
[SerializeField]
|
||||
public LookAtTypes LookAtType;
|
||||
public LookAtType LookAtType;
|
||||
|
||||
[SerializeField]
|
||||
public CurveMapper HorizontalOuter = new CurveMapper(90.0f, 10.0f);
|
||||
@@ -55,7 +46,7 @@ namespace UniVRM10
|
||||
private ILookAtEyeDirectionApplicable _eyeDirectionApplicable;
|
||||
|
||||
internal ILookAtEyeDirectionApplicable EyeDirectionApplicable => _eyeDirectionApplicable;
|
||||
|
||||
|
||||
public LookAtEyeDirection EyeDirection { get; private set; }
|
||||
|
||||
#region LookAtTargetTypes.CalcYawPitchToGaze
|
||||
@@ -150,10 +141,10 @@ namespace UniVRM10
|
||||
}
|
||||
switch (LookAtType)
|
||||
{
|
||||
case LookAtTypes.Bone:
|
||||
case LookAtType.bone:
|
||||
_eyeDirectionApplicable = new LookAtEyeDirectionApplicableToBone(m_leftEye, m_rightEye, HorizontalOuter, HorizontalInner, VerticalDown, VerticalUp);
|
||||
break;
|
||||
case LookAtTypes.Expression:
|
||||
case LookAtType.expression:
|
||||
_eyeDirectionApplicable = new LookAtEyeDirectionApplicableToExpression(HorizontalOuter, HorizontalInner, VerticalDown, VerticalUp);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using VrmLib;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
/// <summary>
|
||||
/// for exporter
|
||||
/// </summary>
|
||||
public class ArrayByteBuffer10
|
||||
{
|
||||
public ArraySegment<byte> Bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_bytes == null)
|
||||
{
|
||||
return new ArraySegment<byte>();
|
||||
}
|
||||
|
||||
return new ArraySegment<byte>(m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
|
||||
Byte[] m_bytes;
|
||||
int m_used = 0;
|
||||
|
||||
public ArrayByteBuffer10(Byte[] bytes = null)
|
||||
{
|
||||
m_bytes = bytes ?? (new byte[] { });
|
||||
}
|
||||
|
||||
public ArrayByteBuffer10(Byte[] bytes, int used)
|
||||
{
|
||||
m_bytes = bytes ?? (new byte[] { });
|
||||
m_used = used;
|
||||
}
|
||||
|
||||
|
||||
public void ExtendCapacity(int byteLength)
|
||||
{
|
||||
var backup = m_bytes;
|
||||
m_bytes = new byte[backup.Length + byteLength];
|
||||
backup.CopyTo(m_bytes, backup.Length);
|
||||
}
|
||||
|
||||
public void Extend(ArraySegment<byte> array, int stride, out int offset, out int length)
|
||||
{
|
||||
var tmp = m_bytes;
|
||||
// alignment
|
||||
var padding = m_used % stride == 0 ? 0 : stride - m_used % stride;
|
||||
|
||||
if (m_bytes == null || m_used + padding + array.Count > m_bytes.Length)
|
||||
{
|
||||
// recreate buffer
|
||||
var newSize = Math.Max(m_used + padding + array.Count, m_bytes.Length * 2);
|
||||
m_bytes = new Byte[newSize];
|
||||
if (m_used > 0)
|
||||
{
|
||||
Buffer.BlockCopy(tmp, 0, m_bytes, 0, m_used);
|
||||
}
|
||||
}
|
||||
if (m_used + padding + array.Count > m_bytes.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(array.Array, array.Offset, m_bytes, m_used + padding, array.Count);
|
||||
|
||||
length = array.Count;
|
||||
offset = m_used + padding;
|
||||
|
||||
|
||||
// var result = new GltfBufferView
|
||||
// {
|
||||
// buffer = 0,
|
||||
// byteLength = array.Length,
|
||||
// byteOffset = m_used + padding,
|
||||
// target = target,
|
||||
// };
|
||||
// if (target == GltfBufferTargetType.ARRAY_BUFFER)
|
||||
// {
|
||||
// result.byteStride = stride;
|
||||
// }
|
||||
|
||||
m_used = m_used + padding + array.Count;
|
||||
// return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c700d6d6fbb38fa4d9662213c58d5725
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,23 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using VrmLib;
|
||||
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class ArrayExtensions
|
||||
{
|
||||
public static Vector2 ToVector2(this float[] src, Vector2 defaultValue = default)
|
||||
{
|
||||
if (src.Length != 2) return defaultValue;
|
||||
|
||||
var v = new Vector2();
|
||||
v.X = src[0];
|
||||
v.Y = src[1];
|
||||
return v;
|
||||
}
|
||||
|
||||
public static Vector3 ToVector3(this float[] src, Vector3 defaultValue = default)
|
||||
{
|
||||
if (src.Length != 3) return defaultValue;
|
||||
@@ -36,74 +22,5 @@ namespace UniVRM10
|
||||
var v = new Quaternion(src[0], src[1], src[2], src[3]);
|
||||
return v;
|
||||
}
|
||||
|
||||
public static TextureInfo GetTexture(this int? nullable, List<Texture> textures)
|
||||
{
|
||||
if (!nullable.TryGetValidIndex(textures.Count, out int index))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var texture = textures[index];
|
||||
return new TextureInfo(texture);
|
||||
}
|
||||
|
||||
public static TextureInfo GetTexture(this int index, List<Texture> textures)
|
||||
{
|
||||
if (index < 0 || index >= textures.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var texture = textures[index];
|
||||
return new TextureInfo(texture);
|
||||
}
|
||||
|
||||
public static int? ToIndex(this TextureInfo texture, List<Texture> textures)
|
||||
{
|
||||
if (texture == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return textures.IndexOfThrow(texture.Texture);
|
||||
}
|
||||
|
||||
public static Vector4 ToVector4(this float[] src, Vector4 defaultValue = default)
|
||||
{
|
||||
switch (src.Length)
|
||||
{
|
||||
case 4:
|
||||
return new Vector4(src[0], src[1], src[2], src[3]);
|
||||
case 3:
|
||||
return new Vector4(src[0], src[1], src[2], 1.0f);
|
||||
case 0:
|
||||
return defaultValue;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearColor ToLinearColor(this float[] src, Vector4 defaultValue)
|
||||
{
|
||||
switch (src.Length)
|
||||
{
|
||||
case 4:
|
||||
return LinearColor.FromLiner(src[0], src[1], src[2], src[3]);
|
||||
case 3:
|
||||
return LinearColor.FromLiner(src[0], src[1], src[2], 1.0f);
|
||||
case 0:
|
||||
return LinearColor.FromLiner(defaultValue);
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public static float[] ToFloat2(this System.Numerics.Vector2 value)
|
||||
{
|
||||
return new float[] { value.X, value.Y };
|
||||
}
|
||||
|
||||
public static float[] ToFloat4(this System.Numerics.Vector4 value)
|
||||
{
|
||||
return new float[] { value.X, value.Y, value.Z, value.W };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace UniVRM10
|
||||
count = self.Count;
|
||||
}
|
||||
var slice = self.Bytes.Slice(offset * stride, count * stride);
|
||||
return storage.AppendToBuffer(bufferIndex, slice, stride);
|
||||
return storage.AppendToBuffer(bufferIndex, slice);
|
||||
}
|
||||
|
||||
static glTFAccessor CreateGltfAccessor(this VrmLib.BufferAccessor self,
|
||||
@@ -116,8 +116,8 @@ namespace UniVRM10
|
||||
sparseValueSpan[i] = value;
|
||||
}
|
||||
|
||||
var sparseIndexView = storage.AppendToBuffer(bufferIndex, sparseIndexBin, 4);
|
||||
var sparseValueView = storage.AppendToBuffer(bufferIndex, sparseValueBin, 12);
|
||||
var sparseIndexView = storage.AppendToBuffer(bufferIndex, sparseIndexBin);
|
||||
var sparseValueView = storage.AppendToBuffer(bufferIndex, sparseValueBin);
|
||||
|
||||
var accessorIndex = storage.Gltf.accessors.Count;
|
||||
var accessor = new glTFAccessor
|
||||
|
||||
29
Assets/VRM10/Runtime/IO/ComponentBuilder.cs
Normal file
29
Assets/VRM10/Runtime/IO/ComponentBuilder.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class ComponentBuilder
|
||||
{
|
||||
#region Util
|
||||
static (Transform, Mesh) GetTransformAndMesh(Transform t)
|
||||
{
|
||||
var skinnedMeshRenderer = t.GetComponent<SkinnedMeshRenderer>();
|
||||
if (skinnedMeshRenderer != null)
|
||||
{
|
||||
return (t, skinnedMeshRenderer.sharedMesh);
|
||||
}
|
||||
|
||||
var filter = t.GetComponent<MeshFilter>();
|
||||
if (filter != null)
|
||||
{
|
||||
return (t, filter.sharedMesh);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
84
Assets/VRM10/Runtime/IO/ExpressionExtensions.cs
Normal file
84
Assets/VRM10/Runtime/IO/ExpressionExtensions.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class ExpressionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// for SubAssetName
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string ExtractName(this Expression expression)
|
||||
{
|
||||
ExpressionKey key =
|
||||
(expression.Preset == ExpressionPreset.custom)
|
||||
? ExpressionKey.CreateCustom(expression.Name)
|
||||
: ExpressionKey.CreateFromPreset(expression.Preset)
|
||||
;
|
||||
return $"Expression.{key}";
|
||||
}
|
||||
|
||||
public static UniVRM10.MorphTargetBinding Build10(this MorphTargetBind bind, GameObject root, RuntimeUnityBuilder.ModelMap loader, VrmLib.Model model)
|
||||
{
|
||||
var libNode = model.Nodes[bind.Node.Value];
|
||||
var node = loader.Nodes[libNode].transform;
|
||||
var mesh = loader.Meshes[libNode.MeshGroup];
|
||||
var relativePath = node.RelativePathFrom(root.transform);
|
||||
// VRM-1.0 では値域は [0-1.0f]
|
||||
return new UniVRM10.MorphTargetBinding(relativePath, bind.Index.Value, bind.Weight.Value * 100.0f);
|
||||
}
|
||||
|
||||
public static UniVRM10.MaterialColorBinding? Build10(this MaterialColorBind bind, IReadOnlyList<VRMShaders.MaterialFactory.MaterialLoadInfo> materials)
|
||||
{
|
||||
var value = new Vector4(bind.TargetValue[0], bind.TargetValue[1], bind.TargetValue[2], bind.TargetValue[3]);
|
||||
var material = materials[bind.Material.Value].Asset;
|
||||
|
||||
var binding = default(UniVRM10.MaterialColorBinding?);
|
||||
if (material != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
binding = new UniVRM10.MaterialColorBinding
|
||||
{
|
||||
MaterialName = material.name, // 名前で持つべき?
|
||||
BindType = bind.Type,
|
||||
TargetValue = value,
|
||||
// BaseValue = material.GetColor(kv.Key),
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
public static UniVRM10.MaterialUVBinding? Build10(this TextureTransformBind bind, IReadOnlyList<VRMShaders.MaterialFactory.MaterialLoadInfo> materials)
|
||||
{
|
||||
var material = materials[bind.Material.Value].Asset;
|
||||
|
||||
var binding = default(UniVRM10.MaterialUVBinding?);
|
||||
if (material != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
binding = new UniVRM10.MaterialUVBinding
|
||||
{
|
||||
MaterialName = material.name, // 名前で持つべき
|
||||
Scaling = new Vector2(bind.Scaling[0], bind.Scaling[1]),
|
||||
Offset = new Vector2(bind.Offset[0], bind.Offset[1]),
|
||||
};
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/VRM10/Runtime/IO/ExpressionExtensions.cs.meta
Normal file
11
Assets/VRM10/Runtime/IO/ExpressionExtensions.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c93dae149b843ca46b028b4e4d845c89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using UniGLTF;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class ImageAdapter
|
||||
{
|
||||
public static VrmLib.Image FromGltf(this glTFImage x, Vrm10Storage storage)
|
||||
{
|
||||
if (x.bufferView == -1)
|
||||
{
|
||||
// 外部参照?
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
var view = storage.Gltf.bufferViews[x.bufferView];
|
||||
|
||||
var buffer = storage.Gltf.buffers[view.buffer];
|
||||
|
||||
// テクスチャの用途を調べる
|
||||
var usage = default(VrmLib.ImageUsage);
|
||||
foreach (var material in storage.Gltf.materials)
|
||||
{
|
||||
var colorImage = GetColorImage(storage, material);
|
||||
if (colorImage == x)
|
||||
{
|
||||
usage |= VrmLib.ImageUsage.Color;
|
||||
}
|
||||
|
||||
var normalImage = GetNormalImage(storage, material);
|
||||
if (normalImage == x)
|
||||
{
|
||||
usage |= VrmLib.ImageUsage.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
var memory = storage.GetBufferBytes(buffer);
|
||||
return new VrmLib.Image(x.name,
|
||||
x.mimeType,
|
||||
usage,
|
||||
memory.Slice(view.byteOffset, view.byteLength));
|
||||
}
|
||||
|
||||
static glTFImage GetTexture(Vrm10Storage storage, int index)
|
||||
{
|
||||
if (index < 0 || index >= storage.Gltf.textures.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var texture = storage.Gltf.textures[index];
|
||||
if (texture.source < 0 || texture.source >= storage.Gltf.images.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return storage.Gltf.images[texture.source];
|
||||
}
|
||||
|
||||
static glTFImage GetColorImage(Vrm10Storage storage, glTFMaterial m)
|
||||
{
|
||||
if (m.pbrMetallicRoughness == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (m.pbrMetallicRoughness.baseColorTexture == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!m.pbrMetallicRoughness.baseColorTexture.index.TryGetValidIndex(storage.TextureCount, out int index))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GetTexture(storage, index);
|
||||
}
|
||||
|
||||
static glTFImage GetNormalImage(Vrm10Storage storage, glTFMaterial m)
|
||||
{
|
||||
if (m.normalTexture == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!m.normalTexture.index.TryGetValidIndex(storage.TextureCount, out int index))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return GetTexture(storage, index);
|
||||
}
|
||||
|
||||
public static glTFImage ToGltf(this VrmLib.Image src, Vrm10Storage storage)
|
||||
{
|
||||
var viewIndex = storage.AppendToBuffer(0, src.Bytes, 1);
|
||||
var gltf = storage.Gltf;
|
||||
return new glTFImage
|
||||
{
|
||||
name = src.Name,
|
||||
mimeType = src.MimeType,
|
||||
bufferView = viewIndex,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d48a6bb715d0d024fa5af64bb63f695e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,263 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using VrmLib.MToon;
|
||||
using VrmLib;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Extensions.VRMC_materials_mtoon;
|
||||
using UniJSON;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class MToonAdapter
|
||||
{
|
||||
// for debug
|
||||
static readonly Vector4 Nan = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN);
|
||||
|
||||
static RenderMode GetRenderMode(string alphaMode, bool isTransparentWithZWrite)
|
||||
{
|
||||
switch (alphaMode)
|
||||
{
|
||||
case "OPAQUE": return RenderMode.Opaque;
|
||||
case "MASK": return RenderMode.Cutout;
|
||||
case "BLEND":
|
||||
{
|
||||
if (isTransparentWithZWrite)
|
||||
{
|
||||
return RenderMode.TransparentWithZWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RenderMode.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static MToonMaterial MToonFromGltf(glTFMaterial material, List<Texture> textures, VRMC_materials_mtoon extension)
|
||||
{
|
||||
var mtoon = new MToonMaterial(material.name);
|
||||
|
||||
var Meta = new MetaDefinition
|
||||
{
|
||||
Implementation = "Santarh/MToon",
|
||||
};
|
||||
var Color = new ColorDefinition
|
||||
{
|
||||
LitColor = material.pbrMetallicRoughness.baseColorFactor.ToLinearColor(Nan),
|
||||
LitMultiplyTexture = material.pbrMetallicRoughness.baseColorTexture?.index.GetTexture(textures),
|
||||
ShadeColor = extension.ShadeFactor.ToLinearColor(Nan),
|
||||
ShadeMultiplyTexture = extension.ShadeMultiplyTexture.GetTexture(textures),
|
||||
CutoutThresholdValue = material.alphaCutoff,
|
||||
};
|
||||
var Outline = new OutlineDefinition
|
||||
{
|
||||
OutlineColorMode = (VrmLib.MToon.OutlineColorMode)extension.OutlineColorMode,
|
||||
OutlineColor = extension.OutlineFactor.ToLinearColor(Nan),
|
||||
OutlineLightingMixValue = extension.OutlineLightingMixFactor.Value,
|
||||
OutlineScaledMaxDistanceValue = extension.OutlineScaledMaxDistanceFactor.Value,
|
||||
OutlineWidthMode = (VrmLib.MToon.OutlineWidthMode)extension.OutlineWidthMode,
|
||||
OutlineWidthValue = extension.OutlineWidthFactor.Value,
|
||||
OutlineWidthMultiplyTexture = extension.OutlineWidthMultiplyTexture.GetTexture(textures),
|
||||
};
|
||||
var Emission = new EmissionDefinition
|
||||
{
|
||||
EmissionColor = material.emissiveFactor.ToLinearColor(Nan),
|
||||
};
|
||||
if (material.emissiveTexture != null)
|
||||
{
|
||||
Emission.EmissionMultiplyTexture = material.emissiveTexture.index.GetTexture(textures);
|
||||
}
|
||||
|
||||
var Lighting = new LightingDefinition
|
||||
{
|
||||
LightingInfluence = new LightingInfluenceDefinition
|
||||
{
|
||||
GiIntensityValue = extension.GiIntensityFactor.Value,
|
||||
LightColorAttenuationValue = extension.LightColorAttenuationFactor.Value,
|
||||
},
|
||||
LitAndShadeMixing = new LitAndShadeMixingDefinition
|
||||
{
|
||||
ShadingShiftValue = extension.ShadingShiftFactor.Value,
|
||||
ShadingToonyValue = extension.ShadingToonyFactor.Value,
|
||||
},
|
||||
Normal = new NormalDefinition
|
||||
{
|
||||
},
|
||||
};
|
||||
if (material.normalTexture != null)
|
||||
{
|
||||
Lighting.Normal.NormalScaleValue = material.normalTexture.scale;
|
||||
Lighting.Normal.NormalTexture = material.normalTexture.index.GetTexture(textures);
|
||||
}
|
||||
|
||||
var MatCap = new MatCapDefinition
|
||||
{
|
||||
AdditiveTexture = extension.AdditiveTexture.GetTexture(textures)
|
||||
};
|
||||
var Rendering = new RenderingDefinition
|
||||
{
|
||||
CullMode = material.doubleSided ? CullMode.Off : CullMode.Back,
|
||||
RenderMode = GetRenderMode(material.alphaMode, extension.TransparentWithZWrite.Value),
|
||||
RenderQueueOffsetNumber = extension.RenderQueueOffsetNumber.Value,
|
||||
};
|
||||
var Rim = new RimDefinition
|
||||
{
|
||||
RimColor = extension.RimFactor.ToLinearColor(Nan),
|
||||
RimMultiplyTexture = extension.RimMultiplyTexture.GetTexture(textures),
|
||||
RimLiftValue = extension.RimLiftFactor.Value,
|
||||
RimFresnelPowerValue = extension.RimFresnelPowerFactor.Value,
|
||||
RimLightingMixValue = extension.RimLightingMixFactor.Value,
|
||||
};
|
||||
|
||||
var TextureOption = new TextureUvCoordsDefinition
|
||||
{
|
||||
UvAnimationMaskTexture = extension.UvAnimationMaskTexture.GetTexture(textures),
|
||||
UvAnimationRotationSpeedValue = extension.UvAnimationRotationSpeedFactor.Value,
|
||||
UvAnimationScrollXSpeedValue = extension.UvAnimationScrollXSpeedFactor.Value,
|
||||
UvAnimationScrollYSpeedValue = extension.UvAnimationScrollYSpeedFactor.Value,
|
||||
};
|
||||
|
||||
if (glTF_KHR_texture_transform.TryGet(material.pbrMetallicRoughness.baseColorTexture, out glTF_KHR_texture_transform t))
|
||||
{
|
||||
TextureOption.MainTextureLeftBottomOriginOffset = t.offset.ToVector2();
|
||||
TextureOption.MainTextureLeftBottomOriginScale = t.scale.ToVector2();
|
||||
}
|
||||
|
||||
mtoon.Definition = new MToonDefinition
|
||||
{
|
||||
Meta = Meta,
|
||||
Color = Color,
|
||||
Outline = Outline,
|
||||
Emission = Emission,
|
||||
Lighting = Lighting,
|
||||
MatCap = MatCap,
|
||||
Rendering = Rendering,
|
||||
Rim = Rim,
|
||||
TextureOption = TextureOption,
|
||||
};
|
||||
|
||||
return mtoon;
|
||||
}
|
||||
|
||||
static (string, bool) GetRenderMode(RenderMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case RenderMode.Opaque: return ("OPAQUE", false);
|
||||
case RenderMode.Cutout: return ("MASK", false);
|
||||
case RenderMode.Transparent: return ("BLEND", false);
|
||||
case RenderMode.TransparentWithZWrite: return ("BLEND", true);
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static glTFMaterial MToonToGltf(this MToonMaterial mtoon, List<Texture> textures)
|
||||
{
|
||||
var material = mtoon.UnlitToGltf(textures);
|
||||
|
||||
var dst = new VRMC_materials_mtoon();
|
||||
|
||||
// Color
|
||||
material.pbrMetallicRoughness.baseColorFactor = mtoon.Definition.Color.LitColor.ToFloat4();
|
||||
if (mtoon.Definition.Color.LitMultiplyTexture != null)
|
||||
{
|
||||
material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = mtoon.Definition.Color.LitMultiplyTexture.ToIndex(textures).Value
|
||||
};
|
||||
}
|
||||
dst.ShadeFactor = mtoon.Definition.Color.ShadeColor.ToFloat3();
|
||||
dst.ShadeMultiplyTexture = mtoon.Definition.Color.ShadeMultiplyTexture.ToIndex(textures);
|
||||
material.alphaCutoff = mtoon.Definition.Color.CutoutThresholdValue;
|
||||
|
||||
// Outline
|
||||
dst.OutlineColorMode = (UniGLTF.Extensions.VRMC_materials_mtoon.OutlineColorMode)mtoon.Definition.Outline.OutlineColorMode;
|
||||
dst.OutlineFactor = mtoon.Definition.Outline.OutlineColor.ToFloat3();
|
||||
dst.OutlineLightingMixFactor = mtoon.Definition.Outline.OutlineLightingMixValue;
|
||||
dst.OutlineScaledMaxDistanceFactor = mtoon.Definition.Outline.OutlineScaledMaxDistanceValue;
|
||||
dst.OutlineWidthMode = (UniGLTF.Extensions.VRMC_materials_mtoon.OutlineWidthMode)mtoon.Definition.Outline.OutlineWidthMode;
|
||||
dst.OutlineWidthFactor = mtoon.Definition.Outline.OutlineWidthValue;
|
||||
dst.OutlineWidthMultiplyTexture = mtoon.Definition.Outline.OutlineWidthMultiplyTexture.ToIndex(textures);
|
||||
|
||||
// Emission
|
||||
material.emissiveFactor = mtoon.Definition.Emission.EmissionColor.ToFloat3();
|
||||
if (mtoon.Definition.Emission.EmissionMultiplyTexture != null)
|
||||
{
|
||||
material.emissiveTexture = new glTFMaterialEmissiveTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(mtoon.Definition.Emission.EmissionMultiplyTexture.Texture).Value
|
||||
};
|
||||
}
|
||||
|
||||
// Light
|
||||
dst.GiIntensityFactor = mtoon.Definition.Lighting.LightingInfluence.GiIntensityValue;
|
||||
dst.LightColorAttenuationFactor = mtoon.Definition.Lighting.LightingInfluence.LightColorAttenuationValue;
|
||||
dst.ShadingShiftFactor = mtoon.Definition.Lighting.LitAndShadeMixing.ShadingShiftValue;
|
||||
dst.ShadingToonyFactor = mtoon.Definition.Lighting.LitAndShadeMixing.ShadingToonyValue;
|
||||
if (mtoon.Definition.Lighting.Normal.NormalTexture != null)
|
||||
{
|
||||
material.normalTexture = new glTFMaterialNormalTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(mtoon.Definition.Lighting.Normal.NormalTexture.Texture).Value,
|
||||
scale = mtoon.Definition.Lighting.Normal.NormalScaleValue
|
||||
};
|
||||
}
|
||||
|
||||
// matcap
|
||||
dst.AdditiveTexture = mtoon.Definition.MatCap.AdditiveTexture.ToIndex(textures);
|
||||
|
||||
// rendering
|
||||
switch (mtoon.Definition.Rendering.CullMode)
|
||||
{
|
||||
case CullMode.Back:
|
||||
material.doubleSided = false;
|
||||
break;
|
||||
|
||||
case CullMode.Off:
|
||||
material.doubleSided = true;
|
||||
break;
|
||||
|
||||
case CullMode.Front:
|
||||
// GLTF not support
|
||||
material.doubleSided = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
(material.alphaMode, dst.TransparentWithZWrite) = GetRenderMode(mtoon.Definition.Rendering.RenderMode);
|
||||
dst.RenderQueueOffsetNumber = mtoon.Definition.Rendering.RenderQueueOffsetNumber;
|
||||
|
||||
// rim
|
||||
dst.RimFactor = mtoon.Definition.Rim.RimColor.ToFloat3();
|
||||
dst.RimMultiplyTexture = mtoon.Definition.Rim.RimMultiplyTexture.ToIndex(textures);
|
||||
dst.RimLiftFactor = mtoon.Definition.Rim.RimLiftValue;
|
||||
dst.RimFresnelPowerFactor = mtoon.Definition.Rim.RimFresnelPowerValue;
|
||||
dst.RimLightingMixFactor = mtoon.Definition.Rim.RimLightingMixValue;
|
||||
|
||||
// texture option
|
||||
dst.UvAnimationMaskTexture = mtoon.Definition.TextureOption.UvAnimationMaskTexture.ToIndex(textures);
|
||||
dst.UvAnimationRotationSpeedFactor = mtoon.Definition.TextureOption.UvAnimationRotationSpeedValue;
|
||||
dst.UvAnimationScrollXSpeedFactor = mtoon.Definition.TextureOption.UvAnimationScrollXSpeedValue;
|
||||
dst.UvAnimationScrollYSpeedFactor = mtoon.Definition.TextureOption.UvAnimationScrollYSpeedValue;
|
||||
if (material.pbrMetallicRoughness.baseColorTexture != null)
|
||||
{
|
||||
var offset = mtoon.Definition.TextureOption.MainTextureLeftBottomOriginOffset;
|
||||
var scale = mtoon.Definition.TextureOption.MainTextureLeftBottomOriginScale;
|
||||
glTF_KHR_texture_transform.Serialize(
|
||||
material.pbrMetallicRoughness.baseColorTexture,
|
||||
(offset.X, offset.Y),
|
||||
(scale.X, scale.Y)
|
||||
);
|
||||
}
|
||||
|
||||
UniGLTF.Extensions.VRMC_materials_mtoon.GltfSerializer.SerializeTo(ref material.extensions, dst);
|
||||
|
||||
return material;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfbed4ddbad0e1941862133ed8219c4c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,312 +0,0 @@
|
||||
using Color = System.Numerics.Vector4;
|
||||
using Material = UniGLTF.glTFMaterial;
|
||||
using System.Collections.Generic;
|
||||
using VrmLib;
|
||||
using VrmLib.MToon;
|
||||
using System;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static partial class Utils
|
||||
{
|
||||
public static void ToProtobuf(this LinearColor color, Action<float> add, bool hasAlpha)
|
||||
{
|
||||
add(color.RGBA.X);
|
||||
add(color.RGBA.Y);
|
||||
add(color.RGBA.Z);
|
||||
if (hasAlpha)
|
||||
{
|
||||
add(color.RGBA.W);
|
||||
}
|
||||
}
|
||||
|
||||
// public static void SetMToonParametersToMaterial(Material material, MToonDefinition parameters, List<Texture> textures)
|
||||
// {
|
||||
// var mtoon = material.Extensions.VRMCMaterialsMtoon;
|
||||
|
||||
// {
|
||||
// var meta = parameters.Meta;
|
||||
// mtoon.Version = meta.VersionNumber.ToString();
|
||||
// }
|
||||
// // TODO:
|
||||
// // {
|
||||
// // var rendering = parameters.Rendering;
|
||||
// // ValidateBlendMode(material, rendering.RenderMode, isChangedByUser: true);
|
||||
// // ValidateCullMode(material, rendering.CullMode);
|
||||
// // ValidateRenderQueue(material, offset: rendering.RenderQueueOffsetNumber);
|
||||
// // }
|
||||
// {
|
||||
// var color = parameters.Color;
|
||||
|
||||
// // SetColor(material, MToonUtils.PropColor, color.LitColor);
|
||||
// color.LitColor.ToProtobuf(mtoon.LitFactor.Add, true);
|
||||
|
||||
// // SetTexture(material, MToonUtils.PropMainTex, color.LitMultiplyTexture, textures);
|
||||
// mtoon.LitMultiplyTexture = textures.IndexOfNullable(color.LitMultiplyTexture.Texture);
|
||||
|
||||
// // SetColor(material, MToonUtils.PropShadeColor, color.ShadeColor);
|
||||
// color.ShadeColor.ToProtobuf(mtoon.ShadeFactor.Add, false);
|
||||
|
||||
// // SetTexture(material, MToonUtils.PropShadeTexture, color.ShadeMultiplyTexture, textures);
|
||||
// mtoon.ShadeMultiplyTexture = textures.IndexOfNullable(color.ShadeMultiplyTexture.Texture);
|
||||
|
||||
// // SetValue(material, MToonUtils.PropCutoff, color.CutoutThresholdValue);
|
||||
// mtoon.CutoutThresholdFactor = color.CutoutThresholdValue;
|
||||
// }
|
||||
// {
|
||||
// var lighting = parameters.Lighting;
|
||||
// {
|
||||
// var prop = lighting.LitAndShadeMixing;
|
||||
// // SetValue(material, MToonUtils.PropShadeShift, prop.ShadingShiftValue);
|
||||
// mtoon.ShadingShiftFactor = prop.ShadingShiftValue;
|
||||
|
||||
// // SetValue(material, MToonUtils.PropShadeToony, prop.ShadingToonyValue);
|
||||
// mtoon.ShadingToonyFactor = prop.ShadingToonyValue;
|
||||
// }
|
||||
// {
|
||||
// var prop = lighting.LightingInfluence;
|
||||
// // SetValue(material, MToonUtils.PropLightColorAttenuation, prop.LightColorAttenuationValue);
|
||||
// mtoon.LightColorAttenuationFactor = prop.LightColorAttenuationValue;
|
||||
|
||||
// // SetValue(material, MToonUtils.PropIndirectLightIntensity, prop.GiIntensityValue);
|
||||
// mtoon.GiIntensityFactor = prop.GiIntensityValue;
|
||||
// }
|
||||
// {
|
||||
// var prop = lighting.Normal;
|
||||
// // SetTexture(material, MToonUtils.PropBumpMap, prop.NormalTexture, textures);
|
||||
// mtoon.NormalTexture = textures.IndexOfNullable(prop.NormalTexture.Texture);
|
||||
|
||||
// // SetValue(material, MToonUtils.PropBumpScale, prop.NormalScaleValue);
|
||||
// mtoon.NormalScaleFactor = prop.NormalScaleValue;
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// var emission = parameters.Emission;
|
||||
// // SetColor(material, MToonUtils.PropEmissionColor, emission.EmissionColor);
|
||||
// emission.EmissionColor.ToProtobuf(mtoon.EmissionFactor.Add, false);
|
||||
|
||||
// // SetTexture(material, MToonUtils.PropEmissionMap, emission.EmissionMultiplyTexture, textures);
|
||||
// mtoon.EmissionMultiplyTexture = textures.IndexOfNullable(emission.EmissionMultiplyTexture.Texture);
|
||||
// }
|
||||
// {
|
||||
// var matcap = parameters.MatCap;
|
||||
// // SetTexture(material, MToonUtils.PropSphereAdd, matcap.AdditiveTexture, textures);
|
||||
// mtoon.AdditiveTexture = textures.IndexOfNullable(matcap.AdditiveTexture.Texture);
|
||||
// }
|
||||
// {
|
||||
// var rim = parameters.Rim;
|
||||
// // SetColor(material, MToonUtils.PropRimColor, rim.RimColor);
|
||||
// rim.RimColor.ToProtobuf(mtoon.RimFactor.Add, false);
|
||||
|
||||
// // SetTexture(material, MToonUtils.PropRimTexture, rim.RimMultiplyTexture, textures);
|
||||
// mtoon.RimMultiplyTexture = textures.IndexOfNullable(rim.RimMultiplyTexture.Texture);
|
||||
|
||||
// // SetValue(material, MToonUtils.PropRimLightingMix, rim.RimLightingMixValue);
|
||||
// mtoon.RimLightingMixFactor = rim.RimLightingMixValue;
|
||||
|
||||
// // SetValue(material, MToonUtils.PropRimFresnelPower, rim.RimFresnelPowerValue);
|
||||
// mtoon.RimFresnelPowerFactor = rim.RimFresnelPowerValue;
|
||||
|
||||
// // SetValue(material, MToonUtils.PropRimLift, rim.RimLiftValue);
|
||||
// mtoon.RimLiftFactor = rim.RimLiftValue;
|
||||
// }
|
||||
// {
|
||||
// var outline = parameters.Outline;
|
||||
// // SetValue(material, MToonUtils.PropOutlineWidth, outline.OutlineWidthValue);
|
||||
// mtoon.OutlineWidthFactor = outline.OutlineWidthValue;
|
||||
|
||||
// // SetTexture(material, MToonUtils.PropOutlineWidthTexture, outline.OutlineWidthMultiplyTexture, textures);
|
||||
// mtoon.OutlineWidthMultiplyTexture = textures.IndexOfNullable(outline.OutlineWidthMultiplyTexture.Texture);
|
||||
|
||||
// // SetValue(material, MToonUtils.PropOutlineScaledMaxDistance, outline.OutlineScaledMaxDistanceValue);
|
||||
// mtoon.OutlineScaledMaxDistanceFactor = outline.OutlineScaledMaxDistanceValue;
|
||||
|
||||
// // SetColor(material, MToonUtils.PropOutlineColor, outline.OutlineColor);
|
||||
// outline.OutlineColor.ToProtobuf(mtoon.OutlineFactor.Add, false);
|
||||
|
||||
// // SetValue(material, MToonUtils.PropOutlineLightingMix, outline.OutlineLightingMixValue);
|
||||
// mtoon.OutlineLightingMixFactor = outline.OutlineLightingMixValue;
|
||||
|
||||
// // ValidateOutlineMode(material, outline.OutlineWidthMode, outline.OutlineColorMode);
|
||||
// }
|
||||
// {
|
||||
// var textureOptions = parameters.TextureOption;
|
||||
// // TODO:
|
||||
// // material.SetTextureScale(MToonUtils.PropMainTex, textureOptions.MainTextureLeftBottomOriginScale);
|
||||
// // material.SetTextureOffset(MToonUtils.PropMainTex, textureOptions.MainTextureLeftBottomOriginOffset);
|
||||
|
||||
// // material.SetTexture(MToonUtils.PropUvAnimMaskTexture, textureOptions.UvAnimationMaskTexture, textures);
|
||||
// mtoon.UvAnimationMaskTexture = textures.IndexOfNullable(textureOptions.UvAnimationMaskTexture.Texture);
|
||||
|
||||
// // material.SetFloat(MToonUtils.PropUvAnimScrollX, textureOptions.UvAnimationScrollXSpeedValue);
|
||||
// mtoon.UvAnimationScrollXSpeedFactor = textureOptions.UvAnimationScrollXSpeedValue;
|
||||
|
||||
// // material.SetFloat(MToonUtils.PropUvAnimScrollY, textureOptions.UvAnimationScrollYSpeedValue);
|
||||
// mtoon.UvAnimationScrollYSpeedFactor = textureOptions.UvAnimationScrollYSpeedValue;
|
||||
|
||||
// // material.SetFloat(MToonUtils.PropUvAnimRotation, textureOptions.UvAnimationRotationSpeedValue);
|
||||
// mtoon.UvAnimationRotationSpeedFactor = textureOptions.UvAnimationRotationSpeedValue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Validate properties and Set hidden properties, keywords.
|
||||
// /// if isBlendModeChangedByUser is true, renderQueue will set specified render mode's default value.
|
||||
// /// </summary>
|
||||
// /// <param name="material"></param>
|
||||
// /// <param name="isBlendModeChangedByUser"></param>
|
||||
// public static void ValidateProperties(Material material, List<Texture> textures, bool isBlendModeChangedByUser = false)
|
||||
// {
|
||||
// ValidateBlendMode(material, (RenderMode)material.GetFloat(MToonUtils.PropBlendMode), isBlendModeChangedByUser);
|
||||
// ValidateNormalMode(material, material.GetTexture(MToonUtils.PropBumpMap, textures) != null);
|
||||
// ValidateOutlineMode(material,
|
||||
// (OutlineWidthMode)material.GetFloat(MToonUtils.PropOutlineWidthMode),
|
||||
// (OutlineColorMode)material.GetFloat(MToonUtils.PropOutlineColorMode));
|
||||
// ValidateDebugMode(material, (DebugMode)material.GetFloat(MToonUtils.PropDebugMode));
|
||||
// ValidateCullMode(material, (CullMode)material.GetFloat(MToonUtils.PropCullMode));
|
||||
|
||||
// var mainTex = material.GetTexture(MToonUtils.PropMainTex, textures);
|
||||
// var shadeTex = material.GetTexture(MToonUtils.PropShadeTexture, textures);
|
||||
// if (mainTex != null && shadeTex == null)
|
||||
// {
|
||||
// material.SetTexture(MToonUtils.PropShadeTexture, mainTex, textures);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private static void ValidateDebugMode(Material material, DebugMode debugMode)
|
||||
// {
|
||||
// switch (debugMode)
|
||||
// {
|
||||
// case DebugMode.None:
|
||||
// SetKeyword(material, MToonUtils.KeyDebugNormal, false);
|
||||
// SetKeyword(material, MToonUtils.KeyDebugLitShadeRate, false);
|
||||
// break;
|
||||
// case DebugMode.Normal:
|
||||
// SetKeyword(material, MToonUtils.KeyDebugNormal, true);
|
||||
// SetKeyword(material, MToonUtils.KeyDebugLitShadeRate, false);
|
||||
// break;
|
||||
// case DebugMode.LitShadeRate:
|
||||
// SetKeyword(material, MToonUtils.KeyDebugNormal, false);
|
||||
// SetKeyword(material, MToonUtils.KeyDebugLitShadeRate, true);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static void ValidateBlendMode(Material material, RenderMode renderMode, bool isChangedByUser)
|
||||
// {
|
||||
// switch (renderMode)
|
||||
// {
|
||||
// case RenderMode.Opaque:
|
||||
// material.SetOverrideTag(MToonUtils.TagRenderTypeKey, MToonUtils.TagRenderTypeValueOpaque);
|
||||
// material.SetInt(MToonUtils.PropSrcBlend, BlendMode.One);
|
||||
// material.SetInt(MToonUtils.PropDstBlend, BlendMode.Zero);
|
||||
// material.SetInt(MToonUtils.PropZWrite, MToonUtils.EnabledIntValue);
|
||||
// material.SetInt(MToonUtils.PropAlphaToMask, MToonUtils.DisabledIntValue);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaTestOn, false);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaBlendOn, false);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaPremultiplyOn, false);
|
||||
// break;
|
||||
// case RenderMode.Cutout:
|
||||
// material.SetOverrideTag(MToonUtils.TagRenderTypeKey, MToonUtils.TagRenderTypeValueTransparentCutout);
|
||||
// material.SetInt(MToonUtils.PropSrcBlend, BlendMode.One);
|
||||
// material.SetInt(MToonUtils.PropDstBlend, BlendMode.Zero);
|
||||
// material.SetInt(MToonUtils.PropZWrite, MToonUtils.EnabledIntValue);
|
||||
// material.SetInt(MToonUtils.PropAlphaToMask, MToonUtils.EnabledIntValue);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaTestOn, true);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaBlendOn, false);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaPremultiplyOn, false);
|
||||
// break;
|
||||
// case RenderMode.Transparent:
|
||||
// material.SetOverrideTag(MToonUtils.TagRenderTypeKey, MToonUtils.TagRenderTypeValueTransparent);
|
||||
// material.SetInt(MToonUtils.PropSrcBlend, BlendMode.SrcAlpha);
|
||||
// material.SetInt(MToonUtils.PropDstBlend, BlendMode.OneMinusSrcAlpha);
|
||||
// material.SetInt(MToonUtils.PropZWrite, MToonUtils.DisabledIntValue);
|
||||
// material.SetInt(MToonUtils.PropAlphaToMask, MToonUtils.DisabledIntValue);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaTestOn, false);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaBlendOn, true);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaPremultiplyOn, false);
|
||||
// break;
|
||||
// case RenderMode.TransparentWithZWrite:
|
||||
// material.SetOverrideTag(MToonUtils.TagRenderTypeKey, MToonUtils.TagRenderTypeValueTransparent);
|
||||
// material.SetInt(MToonUtils.PropSrcBlend, BlendMode.SrcAlpha);
|
||||
// material.SetInt(MToonUtils.PropDstBlend, BlendMode.OneMinusSrcAlpha);
|
||||
// material.SetInt(MToonUtils.PropZWrite, MToonUtils.EnabledIntValue);
|
||||
// material.SetInt(MToonUtils.PropAlphaToMask, MToonUtils.DisabledIntValue);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaTestOn, false);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaBlendOn, true);
|
||||
// SetKeyword(material, MToonUtils.KeyAlphaPremultiplyOn, false);
|
||||
// break;
|
||||
// }
|
||||
|
||||
// if (isChangedByUser)
|
||||
// {
|
||||
// // ValidateRenderQueue(material, offset: 0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var requirement = MToonUtils.GetRenderQueueRequirement(renderMode);
|
||||
// // ValidateRenderQueue(material, offset: material.renderQueue - requirement.DefaultValue);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private static void ValidateRenderQueue(Material material, int offset)
|
||||
// {
|
||||
// var requirement = MToonUtils.GetRenderQueueRequirement(GetBlendMode(material));
|
||||
// var value = Mathf.Clamp(requirement.DefaultValue + offset, requirement.MinValue, requirement.MaxValue);
|
||||
// material.renderQueue = value;
|
||||
// }
|
||||
|
||||
// private static void ValidateOutlineMode(Material material, OutlineWidthMode outlineWidthMode,
|
||||
// OutlineColorMode outlineColorMode)
|
||||
// {
|
||||
// var isFixed = outlineColorMode == OutlineColorMode.FixedColor;
|
||||
// var isMixed = outlineColorMode == OutlineColorMode.MixedLighting;
|
||||
|
||||
// switch (outlineWidthMode)
|
||||
// {
|
||||
// case OutlineWidthMode.None:
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthWorld, false);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthScreen, false);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorFixed, false);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorMixed, false);
|
||||
// break;
|
||||
// case OutlineWidthMode.WorldCoordinates:
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthWorld, true);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthScreen, false);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorFixed, isFixed);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorMixed, isMixed);
|
||||
// break;
|
||||
// case OutlineWidthMode.ScreenCoordinates:
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthWorld, false);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineWidthScreen, true);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorFixed, isFixed);
|
||||
// SetKeyword(material, MToonUtils.KeyOutlineColorMixed, isMixed);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// private static void ValidateNormalMode(Material material, bool requireNormalMapping)
|
||||
// {
|
||||
// SetKeyword(material, MToonUtils.KeyNormalMap, requireNormalMapping);
|
||||
// }
|
||||
|
||||
// private static void ValidateCullMode(Material material, CullMode cullMode)
|
||||
// {
|
||||
// switch (cullMode)
|
||||
// {
|
||||
// case CullMode.Back:
|
||||
// material.SetInt(MToonUtils.PropCullMode, CullMode.Back);
|
||||
// material.SetInt(MToonUtils.PropOutlineCullMode, CullMode.Front);
|
||||
// break;
|
||||
// case CullMode.Front:
|
||||
// material.SetInt(MToonUtils.PropCullMode, CullMode.Front);
|
||||
// material.SetInt(MToonUtils.PropOutlineCullMode, CullMode.Back);
|
||||
// break;
|
||||
// case CullMode.Off:
|
||||
// material.SetInt(MToonUtils.PropCullMode, CullMode.Off);
|
||||
// material.SetInt(MToonUtils.PropOutlineCullMode, CullMode.Front);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 269eb140bd3b26043a6afac332268766
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,230 +0,0 @@
|
||||
using VrmLib;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using UniJSON;
|
||||
using UniGLTF;
|
||||
using System;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class MaterialAdapter
|
||||
{
|
||||
public static Material FromGltf(this glTFMaterial x, List<Texture> textures)
|
||||
{
|
||||
if (UniGLTF.Extensions.VRMC_materials_mtoon.GltfDeserializer.TryGet(x.extensions,
|
||||
out UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon mtoon))
|
||||
{
|
||||
// mtoon
|
||||
return MToonAdapter.MToonFromGltf(x, textures, mtoon);
|
||||
}
|
||||
|
||||
if (glTF_KHR_materials_unlit.IsEnable(x))
|
||||
{
|
||||
// unlit
|
||||
return UnlitFromGltf(x, textures);
|
||||
}
|
||||
|
||||
// PBR
|
||||
return PBRFromGltf(x, textures);
|
||||
}
|
||||
|
||||
public static void LoadCommonParams(this Material self, glTFMaterial material, List<Texture> textures)
|
||||
{
|
||||
var pbr = material.pbrMetallicRoughness;
|
||||
if (pbr.baseColorFactor != null)
|
||||
{
|
||||
self.BaseColorFactor = LinearColor.FromLiner(pbr.baseColorFactor);
|
||||
}
|
||||
var baseColorTexture = pbr.baseColorTexture;
|
||||
if (baseColorTexture != null && baseColorTexture.index.TryGetValidIndex(textures.Count, out int index))
|
||||
{
|
||||
self.BaseColorTexture = new TextureInfo(textures[index]);
|
||||
}
|
||||
|
||||
self.AlphaMode = EnumUtil.Parse<VrmLib.AlphaModeType>(material.alphaMode);
|
||||
self.AlphaCutoff = material.alphaCutoff;
|
||||
self.DoubleSided = material.doubleSided;
|
||||
}
|
||||
|
||||
public static PBRMaterial PBRFromGltf(glTFMaterial material, List<Texture> textures)
|
||||
{
|
||||
var self = new PBRMaterial(material.name);
|
||||
|
||||
self.LoadCommonParams(material, textures);
|
||||
|
||||
//
|
||||
// pbr
|
||||
//
|
||||
var pbr = material.pbrMetallicRoughness;
|
||||
|
||||
// metallic roughness
|
||||
self.MetallicFactor = pbr.metallicFactor;
|
||||
self.RoughnessFactor = pbr.roughnessFactor;
|
||||
var metallicRoughnessTexture = pbr.metallicRoughnessTexture;
|
||||
if (metallicRoughnessTexture != null
|
||||
&& metallicRoughnessTexture.index.TryGetValidIndex(textures.Count, out int metallicRoughnessTextureIndex))
|
||||
{
|
||||
self.MetallicRoughnessTexture = textures[metallicRoughnessTextureIndex];
|
||||
}
|
||||
//
|
||||
// emissive
|
||||
//
|
||||
if (material.emissiveFactor != null)
|
||||
{
|
||||
self.EmissiveFactor = new Vector3(
|
||||
material.emissiveFactor[0],
|
||||
material.emissiveFactor[1],
|
||||
material.emissiveFactor[2]);
|
||||
}
|
||||
var emissiveTexture = material.emissiveTexture;
|
||||
if (emissiveTexture != null
|
||||
&& emissiveTexture.index.TryGetValidIndex(textures.Count, out int emissiveTextureIndex))
|
||||
{
|
||||
self.EmissiveTexture = textures[emissiveTextureIndex];
|
||||
}
|
||||
//
|
||||
// normal
|
||||
//
|
||||
var normalTexture = material.normalTexture;
|
||||
if (normalTexture != null
|
||||
&& normalTexture.index.TryGetValidIndex(textures.Count, out int normalTextureIndex))
|
||||
{
|
||||
self.NormalTexture = textures[normalTextureIndex];
|
||||
}
|
||||
//
|
||||
// occlusion
|
||||
//
|
||||
var occlusionTexture = material.occlusionTexture;
|
||||
if (occlusionTexture != null
|
||||
&& occlusionTexture.index.TryGetValidIndex(textures.Count, out int occlusionTextureIndex))
|
||||
{
|
||||
self.OcclusionTexture = textures[occlusionTextureIndex];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
public static UnlitMaterial UnlitFromGltf(glTFMaterial material, List<Texture> textures)
|
||||
{
|
||||
var unlit = new UnlitMaterial(material.name);
|
||||
unlit.LoadCommonParams(material, textures);
|
||||
return unlit;
|
||||
}
|
||||
|
||||
static string CastAlphaMode(VrmLib.AlphaModeType alphaMode)
|
||||
{
|
||||
if (alphaMode == AlphaModeType.BLEND_ZWRITE)
|
||||
{
|
||||
return "BLEND";
|
||||
}
|
||||
return alphaMode.ToString();
|
||||
}
|
||||
|
||||
static glTFMaterial ToGltf(this VrmLib.Material src, List<Texture> textures)
|
||||
{
|
||||
var material = new glTFMaterial
|
||||
{
|
||||
name = src.Name,
|
||||
pbrMetallicRoughness = new glTFPbrMetallicRoughness
|
||||
{
|
||||
baseColorFactor = src.BaseColorFactor.ToFloat4(),
|
||||
},
|
||||
alphaMode = CastAlphaMode(src.AlphaMode),
|
||||
alphaCutoff = src.AlphaCutoff,
|
||||
doubleSided = src.DoubleSided,
|
||||
};
|
||||
if (src.BaseColorTexture != null)
|
||||
{
|
||||
material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(src.BaseColorTexture.Texture).Value,
|
||||
};
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
public static glTFMaterial PBRToGltf(this PBRMaterial pbr, List<Texture> textures)
|
||||
{
|
||||
var material = pbr.ToGltf(textures);
|
||||
|
||||
// MetallicRoughness
|
||||
material.pbrMetallicRoughness.baseColorFactor = pbr.BaseColorFactor.ToFloat4();
|
||||
if (pbr.BaseColorTexture != null)
|
||||
{
|
||||
material.pbrMetallicRoughness.baseColorTexture = new glTFMaterialBaseColorTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(pbr.BaseColorTexture.Texture).Value,
|
||||
};
|
||||
}
|
||||
material.pbrMetallicRoughness.metallicFactor = pbr.MetallicFactor;
|
||||
material.pbrMetallicRoughness.roughnessFactor = pbr.RoughnessFactor;
|
||||
if (pbr.MetallicRoughnessTexture != null)
|
||||
{
|
||||
material.pbrMetallicRoughness.metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(pbr.MetallicRoughnessTexture).Value,
|
||||
};
|
||||
}
|
||||
|
||||
// Normal
|
||||
if (pbr.NormalTexture != null)
|
||||
{
|
||||
material.normalTexture = new glTFMaterialNormalTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(pbr.NormalTexture).Value,
|
||||
scale = pbr.NormalTextureScale
|
||||
};
|
||||
}
|
||||
|
||||
// Occlusion
|
||||
if (pbr.OcclusionTexture != null)
|
||||
{
|
||||
material.occlusionTexture = new glTFMaterialOcclusionTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(pbr.OcclusionTexture).Value,
|
||||
strength = pbr.OcclusionTextureStrength,
|
||||
};
|
||||
}
|
||||
|
||||
// Emissive
|
||||
if (pbr.EmissiveTexture != null)
|
||||
{
|
||||
material.emissiveTexture = new glTFMaterialEmissiveTextureInfo
|
||||
{
|
||||
index = textures.IndexOfNullable(pbr.EmissiveTexture).Value,
|
||||
};
|
||||
}
|
||||
material.emissiveFactor = pbr.EmissiveFactor.ToFloat3();
|
||||
|
||||
// AlphaMode
|
||||
material.alphaMode = CastAlphaMode(pbr.AlphaMode);
|
||||
|
||||
// AlphaCutoff
|
||||
material.alphaCutoff = pbr.AlphaCutoff;
|
||||
|
||||
// DoubleSided
|
||||
material.doubleSided = pbr.DoubleSided;
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
public static glTFMaterial UnlitToGltf(this UnlitMaterial unlit, List<Texture> textures)
|
||||
{
|
||||
var material = unlit.ToGltf(textures);
|
||||
|
||||
if (!(material.extensions is glTFExtensionExport extensions))
|
||||
{
|
||||
extensions = new glTFExtensionExport();
|
||||
material.extensions = extensions;
|
||||
}
|
||||
extensions.Add(
|
||||
glTF_KHR_materials_unlit.ExtensionName,
|
||||
new ArraySegment<byte>(glTF_KHR_materials_unlit.Raw));
|
||||
|
||||
material.pbrMetallicRoughness.roughnessFactor = 0.9f;
|
||||
material.pbrMetallicRoughness.metallicFactor = 0.0f;
|
||||
|
||||
return material;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user