mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-22 06:57:25 -05:00
Convert CRLF to LF
This commit is contained in:
parent
a850c55e54
commit
384122913b
|
|
@ -1,241 +1,241 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEditor.Build.Reporting;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class VRMExportUnityPackage
|
||||
{
|
||||
static string GetDesktop()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/VRM";
|
||||
}
|
||||
|
||||
const string DATE_FORMAT = "yyyyMMdd";
|
||||
const string PREFIX = "UniVRM";
|
||||
|
||||
static string System(string dir, string fileName, string args)
|
||||
{
|
||||
// Start the child process.
|
||||
var p = new System.Diagnostics.Process();
|
||||
// Redirect the output stream of the child process.
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.FileName = fileName;
|
||||
p.StartInfo.Arguments = args;
|
||||
p.StartInfo.WorkingDirectory = dir;
|
||||
if (!p.Start())
|
||||
{
|
||||
return "ERROR";
|
||||
}
|
||||
// Do not wait for the child process to exit before
|
||||
// reading to the end of its redirected stream.
|
||||
// p.WaitForExit();
|
||||
// Read the output stream first and then wait.
|
||||
string output = p.StandardOutput.ReadToEnd();
|
||||
string err = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
|
||||
if (string.IsNullOrEmpty(output))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
//const string GIT_PATH = "C:\\Program Files\\Git\\mingw64\\bin\\git.exe";
|
||||
const string GIT_PATH = "C:\\Program Files\\Git\\bin\\git.exe";
|
||||
|
||||
static string GetGitHash(string path)
|
||||
{
|
||||
return System(path, "git.exe", "rev-parse HEAD").Trim();
|
||||
}
|
||||
|
||||
#if false
|
||||
[MenuItem("VRM/git")]
|
||||
static void X()
|
||||
{
|
||||
var path = Application.dataPath;
|
||||
Debug.LogFormat("{0} => '{1}'", path, GetGitHash(path));
|
||||
}
|
||||
#endif
|
||||
|
||||
static string GetPath(string folder, string prefix)
|
||||
{
|
||||
//var date = DateTime.Today.ToString(DATE_FORMAT);
|
||||
|
||||
var path = string.Format("{0}/{1}-{2}_{3}.unitypackage",
|
||||
folder,
|
||||
prefix,
|
||||
VRMVersion.VERSION,
|
||||
GetGitHash(Application.dataPath + "/VRM").Substring(0, 4)
|
||||
).Replace("\\", "/");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static IEnumerable<string> EnumerateFiles(string path, Func<string, bool> isExclude=null)
|
||||
{
|
||||
path = path.Replace("\\", "/");
|
||||
|
||||
if (Path.GetFileName(path).StartsWith(".git"))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (isExclude != null && isExclude(path))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var child in Directory.GetFileSystemEntries(path))
|
||||
{
|
||||
foreach (var x in EnumerateFiles(child, isExclude))
|
||||
{
|
||||
yield return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Path.GetExtension(path).ToLower() == ".meta")
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return path;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Build(string[] levels)
|
||||
{
|
||||
var buildPath = Path.GetFullPath(Application.dataPath + "/../build/build.exe");
|
||||
Debug.LogFormat("{0}", buildPath);
|
||||
var build = BuildPipeline.BuildPlayer(levels,
|
||||
buildPath,
|
||||
BuildTarget.StandaloneWindows,
|
||||
BuildOptions.None
|
||||
);
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
var iSuccess = build.summary.result != BuildResult.Succeeded;
|
||||
#else
|
||||
var iSuccess = !string.IsNullOrEmpty(build);
|
||||
#endif
|
||||
return iSuccess;
|
||||
}
|
||||
|
||||
public static bool BuildTestScene()
|
||||
{
|
||||
var levels = new string[] { "Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.unity" };
|
||||
return Build(levels);
|
||||
}
|
||||
|
||||
#if VRM_DEVELOP
|
||||
[MenuItem(VRMVersion.VRM_VERSION + "/Export unitypackage")]
|
||||
#endif
|
||||
public static void CreateUnityPackageWithBuild()
|
||||
{
|
||||
var folder = GetDesktop();
|
||||
if (!Directory.Exists(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
CreateUnityPackage(folder, true);
|
||||
}
|
||||
|
||||
public static void CreateUnityPackage()
|
||||
{
|
||||
CreateUnityPackage(Path.GetFullPath(Path.Combine(Application.dataPath, "..")), false);
|
||||
}
|
||||
|
||||
static bool EndsWith(string path, params string[] exts)
|
||||
{
|
||||
foreach(var ext in exts)
|
||||
{
|
||||
if (path.EndsWith(ext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(path.EndsWith(ext + ".meta"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ExcludeCsProj(string path)
|
||||
{
|
||||
/*
|
||||
if(EndsWith(path, "csproj", "sln", "csproj.user", "psess", "bin", "obj", "vsp", "vspx"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
if (path.EndsWith("/UniJSON/Profiling.meta"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniJSON/Profiling"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniGLTF/doc"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniHumanoid/doc"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void CreateUnityPackage(string folder, bool build)
|
||||
{
|
||||
if (build)
|
||||
{
|
||||
// まずビルドする
|
||||
/*var iSuccess = */BuildTestScene();
|
||||
}
|
||||
|
||||
var path = GetPath(folder, PREFIX);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Debug.LogErrorFormat("{0} is already exists", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// 本体
|
||||
{
|
||||
var files = EnumerateFiles("Assets/VRM", ExcludeCsProj).ToArray();
|
||||
Debug.LogFormat("{0}", string.Join("", files.Select((x, i) => string.Format("[{0:##0}] {1}\n", i, x)).ToArray()));
|
||||
AssetDatabase.ExportPackage(files
|
||||
, path,
|
||||
ExportPackageOptions.Default);
|
||||
}
|
||||
|
||||
// サンプル
|
||||
{
|
||||
AssetDatabase.ExportPackage(EnumerateFiles("Assets/VRM.Samples").Concat(EnumerateFiles("Assets/StreamingAssets")).ToArray()
|
||||
, GetPath(folder, PREFIX + "-RuntimeLoaderSample"),
|
||||
ExportPackageOptions.Default);
|
||||
}
|
||||
|
||||
Debug.LogFormat("exported: {0}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
using UnityEditor.Build.Reporting;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class VRMExportUnityPackage
|
||||
{
|
||||
static string GetDesktop()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/VRM";
|
||||
}
|
||||
|
||||
const string DATE_FORMAT = "yyyyMMdd";
|
||||
const string PREFIX = "UniVRM";
|
||||
|
||||
static string System(string dir, string fileName, string args)
|
||||
{
|
||||
// Start the child process.
|
||||
var p = new System.Diagnostics.Process();
|
||||
// Redirect the output stream of the child process.
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.FileName = fileName;
|
||||
p.StartInfo.Arguments = args;
|
||||
p.StartInfo.WorkingDirectory = dir;
|
||||
if (!p.Start())
|
||||
{
|
||||
return "ERROR";
|
||||
}
|
||||
// Do not wait for the child process to exit before
|
||||
// reading to the end of its redirected stream.
|
||||
// p.WaitForExit();
|
||||
// Read the output stream first and then wait.
|
||||
string output = p.StandardOutput.ReadToEnd();
|
||||
string err = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
|
||||
if (string.IsNullOrEmpty(output))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
//const string GIT_PATH = "C:\\Program Files\\Git\\mingw64\\bin\\git.exe";
|
||||
const string GIT_PATH = "C:\\Program Files\\Git\\bin\\git.exe";
|
||||
|
||||
static string GetGitHash(string path)
|
||||
{
|
||||
return System(path, "git.exe", "rev-parse HEAD").Trim();
|
||||
}
|
||||
|
||||
#if false
|
||||
[MenuItem("VRM/git")]
|
||||
static void X()
|
||||
{
|
||||
var path = Application.dataPath;
|
||||
Debug.LogFormat("{0} => '{1}'", path, GetGitHash(path));
|
||||
}
|
||||
#endif
|
||||
|
||||
static string GetPath(string folder, string prefix)
|
||||
{
|
||||
//var date = DateTime.Today.ToString(DATE_FORMAT);
|
||||
|
||||
var path = string.Format("{0}/{1}-{2}_{3}.unitypackage",
|
||||
folder,
|
||||
prefix,
|
||||
VRMVersion.VERSION,
|
||||
GetGitHash(Application.dataPath + "/VRM").Substring(0, 4)
|
||||
).Replace("\\", "/");
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static IEnumerable<string> EnumerateFiles(string path, Func<string, bool> isExclude=null)
|
||||
{
|
||||
path = path.Replace("\\", "/");
|
||||
|
||||
if (Path.GetFileName(path).StartsWith(".git"))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (isExclude != null && isExclude(path))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var child in Directory.GetFileSystemEntries(path))
|
||||
{
|
||||
foreach (var x in EnumerateFiles(child, isExclude))
|
||||
{
|
||||
yield return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Path.GetExtension(path).ToLower() == ".meta")
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return path;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Build(string[] levels)
|
||||
{
|
||||
var buildPath = Path.GetFullPath(Application.dataPath + "/../build/build.exe");
|
||||
Debug.LogFormat("{0}", buildPath);
|
||||
var build = BuildPipeline.BuildPlayer(levels,
|
||||
buildPath,
|
||||
BuildTarget.StandaloneWindows,
|
||||
BuildOptions.None
|
||||
);
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
var iSuccess = build.summary.result != BuildResult.Succeeded;
|
||||
#else
|
||||
var iSuccess = !string.IsNullOrEmpty(build);
|
||||
#endif
|
||||
return iSuccess;
|
||||
}
|
||||
|
||||
public static bool BuildTestScene()
|
||||
{
|
||||
var levels = new string[] { "Assets/VRM.Samples/Scenes/VRMRuntimeLoaderSample.unity" };
|
||||
return Build(levels);
|
||||
}
|
||||
|
||||
#if VRM_DEVELOP
|
||||
[MenuItem(VRMVersion.VRM_VERSION + "/Export unitypackage")]
|
||||
#endif
|
||||
public static void CreateUnityPackageWithBuild()
|
||||
{
|
||||
var folder = GetDesktop();
|
||||
if (!Directory.Exists(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
CreateUnityPackage(folder, true);
|
||||
}
|
||||
|
||||
public static void CreateUnityPackage()
|
||||
{
|
||||
CreateUnityPackage(Path.GetFullPath(Path.Combine(Application.dataPath, "..")), false);
|
||||
}
|
||||
|
||||
static bool EndsWith(string path, params string[] exts)
|
||||
{
|
||||
foreach(var ext in exts)
|
||||
{
|
||||
if (path.EndsWith(ext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(path.EndsWith(ext + ".meta"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ExcludeCsProj(string path)
|
||||
{
|
||||
/*
|
||||
if(EndsWith(path, "csproj", "sln", "csproj.user", "psess", "bin", "obj", "vsp", "vspx"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
if (path.EndsWith("/UniJSON/Profiling.meta"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniJSON/Profiling"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniGLTF/doc"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (path.EndsWith("/UniHumanoid/doc"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void CreateUnityPackage(string folder, bool build)
|
||||
{
|
||||
if (build)
|
||||
{
|
||||
// まずビルドする
|
||||
/*var iSuccess = */BuildTestScene();
|
||||
}
|
||||
|
||||
var path = GetPath(folder, PREFIX);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Debug.LogErrorFormat("{0} is already exists", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// 本体
|
||||
{
|
||||
var files = EnumerateFiles("Assets/VRM", ExcludeCsProj).ToArray();
|
||||
Debug.LogFormat("{0}", string.Join("", files.Select((x, i) => string.Format("[{0:##0}] {1}\n", i, x)).ToArray()));
|
||||
AssetDatabase.ExportPackage(files
|
||||
, path,
|
||||
ExportPackageOptions.Default);
|
||||
}
|
||||
|
||||
// サンプル
|
||||
{
|
||||
AssetDatabase.ExportPackage(EnumerateFiles("Assets/VRM.Samples").Concat(EnumerateFiles("Assets/StreamingAssets")).ToArray()
|
||||
, GetPath(folder, PREFIX + "-RuntimeLoaderSample"),
|
||||
ExportPackageOptions.Default);
|
||||
}
|
||||
|
||||
Debug.LogFormat("exported: {0}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,106 +1,106 @@
|
|||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using UniJSON;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class JsonExtensions
|
||||
{
|
||||
public static void SetValue<T>(this ListTreeNode<JsonValue> node, string key, T value)
|
||||
{
|
||||
var f = new JsonFormatter();
|
||||
f.Serialize(value);
|
||||
var p = Utf8String.From(key);
|
||||
var bytes = f.GetStoreBytes();
|
||||
node.SetValue(p, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public class VRMImportExportTests
|
||||
{
|
||||
[Test]
|
||||
public void ImportExportTest()
|
||||
{
|
||||
var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm");
|
||||
var context = new VRMImporterContext();
|
||||
context.ParseGlb(File.ReadAllBytes(path.FullPath));
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
|
||||
using (new ActionDisposer(() => { GameObject.DestroyImmediate(context.Root); }))
|
||||
{
|
||||
var importJson = JsonParser.Parse(context.Json);
|
||||
importJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION);
|
||||
importJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION);
|
||||
importJson.SetValue("/scene", 0);
|
||||
importJson.SetValue("/materials/*/doubleSided", false);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 });
|
||||
importJson.SetValue("/accessors/*/normalized", false);
|
||||
importJson.RemoveValue(Utf8String.From("/nodes/*/extras"));
|
||||
/*
|
||||
importJson.SetValue("/bufferViews/12/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/13/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/14/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/15/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/22/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/29/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/45/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/46/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/47/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/201/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/202/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/203/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/204/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/211/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/212/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/213/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/214/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/215/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/243/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/247/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/248/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/249/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/250/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/251/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/252/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/253/byteStride", 64);
|
||||
*/
|
||||
importJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
|
||||
|
||||
var vrm = VRMExporter.Export(context.Root);
|
||||
var exportJson = JsonParser.Parse(vrm.ToJson());
|
||||
|
||||
/*
|
||||
foreach (var kv in importJson.Diff(exportJson))
|
||||
{
|
||||
Debug.Log(kv);
|
||||
}
|
||||
|
||||
Assert.AreEqual(importJson, exportJson);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MeshCoyTest()
|
||||
{
|
||||
var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm");
|
||||
var context = new VRMImporterContext();
|
||||
context.ParseGlb(File.ReadAllBytes(path.FullPath));
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
|
||||
foreach (var mesh in context.Meshes)
|
||||
{
|
||||
var src = mesh.Mesh;
|
||||
var dst = src.Copy(true);
|
||||
MeshTests.MeshEquals(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using UniJSON;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class JsonExtensions
|
||||
{
|
||||
public static void SetValue<T>(this ListTreeNode<JsonValue> node, string key, T value)
|
||||
{
|
||||
var f = new JsonFormatter();
|
||||
f.Serialize(value);
|
||||
var p = Utf8String.From(key);
|
||||
var bytes = f.GetStoreBytes();
|
||||
node.SetValue(p, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public class VRMImportExportTests
|
||||
{
|
||||
[Test]
|
||||
public void ImportExportTest()
|
||||
{
|
||||
var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm");
|
||||
var context = new VRMImporterContext();
|
||||
context.ParseGlb(File.ReadAllBytes(path.FullPath));
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
|
||||
using (new ActionDisposer(() => { GameObject.DestroyImmediate(context.Root); }))
|
||||
{
|
||||
var importJson = JsonParser.Parse(context.Json);
|
||||
importJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION);
|
||||
importJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION);
|
||||
importJson.SetValue("/scene", 0);
|
||||
importJson.SetValue("/materials/*/doubleSided", false);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0);
|
||||
//importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 });
|
||||
importJson.SetValue("/accessors/*/normalized", false);
|
||||
importJson.RemoveValue(Utf8String.From("/nodes/*/extras"));
|
||||
/*
|
||||
importJson.SetValue("/bufferViews/12/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/13/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/14/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/15/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/22/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/29/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/45/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/46/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/47/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/201/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/202/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/203/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/204/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/211/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/212/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/213/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/214/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/215/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/243/byteStride", 4);
|
||||
importJson.SetValue("/bufferViews/247/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/248/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/249/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/250/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/251/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/252/byteStride", 64);
|
||||
importJson.SetValue("/bufferViews/253/byteStride", 64);
|
||||
*/
|
||||
importJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));
|
||||
|
||||
var vrm = VRMExporter.Export(context.Root);
|
||||
var exportJson = JsonParser.Parse(vrm.ToJson());
|
||||
|
||||
/*
|
||||
foreach (var kv in importJson.Diff(exportJson))
|
||||
{
|
||||
Debug.Log(kv);
|
||||
}
|
||||
|
||||
Assert.AreEqual(importJson, exportJson);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MeshCoyTest()
|
||||
{
|
||||
var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm");
|
||||
var context = new VRMImporterContext();
|
||||
context.ParseGlb(File.ReadAllBytes(path.FullPath));
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
|
||||
foreach (var mesh in context.Meshes)
|
||||
{
|
||||
var src = mesh.Mesh;
|
||||
var dst = src.Copy(true);
|
||||
MeshTests.MeshEquals(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,72 +1,72 @@
|
|||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VRMMaterialTests
|
||||
{
|
||||
/*
|
||||
[Test]
|
||||
public void ExportTest()
|
||||
{
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_texture");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("OPAQUE", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_transparent");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_cutout");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("MASK", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_transparent_zwrite");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_opaque");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("OPAQUE", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_transparent");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_cutout");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("MASK", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_culloff");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.True(exported.doubleSided);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VRMMaterialTests
|
||||
{
|
||||
/*
|
||||
[Test]
|
||||
public void ExportTest()
|
||||
{
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_texture");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("OPAQUE", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_transparent");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_cutout");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("MASK", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/vrm_unlit_transparent_zwrite");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_opaque");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("OPAQUE", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_transparent");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("BLEND", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_cutout");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.AreEqual("MASK", exported.alphaMode);
|
||||
}
|
||||
{
|
||||
var material = Resources.Load<Material>("Materials/mtoon_culloff");
|
||||
var exporter = new VRMMaterialExporter();
|
||||
var exported = exporter.ExportMaterial(material, null);
|
||||
Assert.NotNull(exported.extensions.KHR_materials_unlit);
|
||||
Assert.True(exported.doubleSided);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,73 +1,73 @@
|
|||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class AIUEO : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public VRMBlendShapeProxy BlendShapes;
|
||||
private void Reset()
|
||||
{
|
||||
BlendShapes = GetComponent<VRMBlendShapeProxy>();
|
||||
}
|
||||
|
||||
Coroutine m_coroutine;
|
||||
|
||||
[SerializeField]
|
||||
float m_wait = 0.5f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (BlendShapes == null)
|
||||
{
|
||||
BlendShapes = GetComponent<VRM.VRMBlendShapeProxy>();
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator RoutineNest(BlendShapePreset preset, float velocity, float wait)
|
||||
{
|
||||
for (var value = 0.0f; value <= 1.0f; value += velocity)
|
||||
{
|
||||
BlendShapes.ImmediatelySetValue(preset, value);
|
||||
yield return null;
|
||||
}
|
||||
BlendShapes.ImmediatelySetValue(preset, 1.0f);
|
||||
yield return new WaitForSeconds(wait);
|
||||
for (var value = 1.0f; value >= 0; value -= velocity)
|
||||
{
|
||||
BlendShapes.ImmediatelySetValue(preset, value);
|
||||
yield return null;
|
||||
}
|
||||
BlendShapes.ImmediatelySetValue(preset, 0);
|
||||
yield return new WaitForSeconds(wait * 2);
|
||||
}
|
||||
|
||||
IEnumerator Routine()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
var velocity = 0.1f;
|
||||
|
||||
yield return RoutineNest(BlendShapePreset.A, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.I, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.U, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.E, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.O, velocity, m_wait);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_coroutine = StartCoroutine(Routine());
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
StopCoroutine(m_coroutine);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class AIUEO : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public VRMBlendShapeProxy BlendShapes;
|
||||
private void Reset()
|
||||
{
|
||||
BlendShapes = GetComponent<VRMBlendShapeProxy>();
|
||||
}
|
||||
|
||||
Coroutine m_coroutine;
|
||||
|
||||
[SerializeField]
|
||||
float m_wait = 0.5f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (BlendShapes == null)
|
||||
{
|
||||
BlendShapes = GetComponent<VRM.VRMBlendShapeProxy>();
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator RoutineNest(BlendShapePreset preset, float velocity, float wait)
|
||||
{
|
||||
for (var value = 0.0f; value <= 1.0f; value += velocity)
|
||||
{
|
||||
BlendShapes.ImmediatelySetValue(preset, value);
|
||||
yield return null;
|
||||
}
|
||||
BlendShapes.ImmediatelySetValue(preset, 1.0f);
|
||||
yield return new WaitForSeconds(wait);
|
||||
for (var value = 1.0f; value >= 0; value -= velocity)
|
||||
{
|
||||
BlendShapes.ImmediatelySetValue(preset, value);
|
||||
yield return null;
|
||||
}
|
||||
BlendShapes.ImmediatelySetValue(preset, 0);
|
||||
yield return new WaitForSeconds(wait * 2);
|
||||
}
|
||||
|
||||
IEnumerator Routine()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
var velocity = 0.1f;
|
||||
|
||||
yield return RoutineNest(BlendShapePreset.A, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.I, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.U, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.E, velocity, m_wait);
|
||||
yield return RoutineNest(BlendShapePreset.O, velocity, m_wait);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_coroutine = StartCoroutine(Routine());
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
StopCoroutine(m_coroutine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class CanvasManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public Button LoadVRMButton;
|
||||
|
||||
[SerializeField]
|
||||
public Button LoadBVHButton;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
LoadVRMButton = GameObject.FindObjectsOfType<Button>().FirstOrDefault(x => x.name == "LoadVRM");
|
||||
LoadBVHButton = GameObject.FindObjectsOfType<Button>().FirstOrDefault(x => x.name == "LoadBVH");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class CanvasManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public Button LoadVRMButton;
|
||||
|
||||
[SerializeField]
|
||||
public Button LoadBVHButton;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
LoadVRMButton = GameObject.FindObjectsOfType<Button>().FirstOrDefault(x => x.name == "LoadVRM");
|
||||
LoadBVHButton = GameObject.FindObjectsOfType<Button>().FirstOrDefault(x => x.name == "LoadBVH");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,118 +1,118 @@
|
|||
#if UNITY_STANDALONE_WIN
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class FileDialogForWindows
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
#region GetOpenFileName
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public class OpenFileName
|
||||
{
|
||||
public int structSize = 0;
|
||||
public IntPtr dlgOwner = IntPtr.Zero;
|
||||
public IntPtr instance = IntPtr.Zero;
|
||||
public String filter = null;
|
||||
public String customFilter = null;
|
||||
public int maxCustFilter = 0;
|
||||
public int filterIndex = 0;
|
||||
public String file = null;
|
||||
public int maxFile = 0;
|
||||
public String fileTitle = null;
|
||||
public int maxFileTitle = 0;
|
||||
public String initialDir = null;
|
||||
public String title = null;
|
||||
public int flags = 0;
|
||||
public short fileOffset = 0;
|
||||
public short fileExtension = 0;
|
||||
public String defExt = null;
|
||||
public IntPtr custData = IntPtr.Zero;
|
||||
public IntPtr hook = IntPtr.Zero;
|
||||
public String templateName = null;
|
||||
public IntPtr reservedPtr = IntPtr.Zero;
|
||||
public int reservedInt = 0;
|
||||
public int flagsEx = 0;
|
||||
}
|
||||
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
|
||||
/*
|
||||
public static bool GetOpenFileName1([In, Out] OpenFileName ofn)
|
||||
{
|
||||
return GetOpenFileName(ofn);
|
||||
}
|
||||
*/
|
||||
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
|
||||
|
||||
static string Filter(params string[] filters)
|
||||
{
|
||||
return string.Join("\0", filters) + "\0";
|
||||
}
|
||||
public static string FileDialog(string title, params string[] extensions)
|
||||
{
|
||||
OpenFileName ofn = new OpenFileName();
|
||||
ofn.structSize = Marshal.SizeOf(ofn);
|
||||
|
||||
var filters = new List<string>();
|
||||
filters.Add("All Files"); filters.Add("*.*");
|
||||
foreach(var ext in extensions)
|
||||
{
|
||||
filters.Add(ext); filters.Add("*" + ext);
|
||||
}
|
||||
ofn.filter = Filter(filters.ToArray());
|
||||
ofn.filterIndex = 2;
|
||||
ofn.file = new string(new char[256]);
|
||||
ofn.maxFile = ofn.file.Length;
|
||||
ofn.fileTitle = new string(new char[64]);
|
||||
ofn.maxFileTitle = ofn.fileTitle.Length;
|
||||
ofn.initialDir = UnityEngine.Application.dataPath;
|
||||
ofn.title = title;
|
||||
//ofn.defExt = "PNG";
|
||||
ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR
|
||||
if (!GetOpenFileName(ofn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ofn.file;
|
||||
}
|
||||
public static string SaveDialog(string title, string path)
|
||||
{
|
||||
var extension = Path.GetExtension(path);
|
||||
OpenFileName ofn = new OpenFileName();
|
||||
ofn.structSize = Marshal.SizeOf(ofn);
|
||||
ofn.filter = Filter("All Files", "*.*", extension, "*" + extension);
|
||||
ofn.filterIndex = 2;
|
||||
var chars = new char[256];
|
||||
var it = Path.GetFileName(path).GetEnumerator();
|
||||
for (int i = 0; i < chars.Length && it.MoveNext(); ++i)
|
||||
{
|
||||
chars[i] = it.Current;
|
||||
}
|
||||
ofn.file = new string(chars);
|
||||
ofn.maxFile = ofn.file.Length;
|
||||
ofn.fileTitle = new string(new char[64]);
|
||||
ofn.maxFileTitle = ofn.fileTitle.Length;
|
||||
ofn.initialDir = Path.GetDirectoryName(path);
|
||||
ofn.title = title;
|
||||
//ofn.defExt = "PNG";
|
||||
ofn.flags = 0x00000002 | 0x00000004; // OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
|
||||
if (!GetSaveFileName(ofn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ofn.file;
|
||||
}
|
||||
#endregion
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if UNITY_STANDALONE_WIN
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public static class FileDialogForWindows
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
#region GetOpenFileName
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public class OpenFileName
|
||||
{
|
||||
public int structSize = 0;
|
||||
public IntPtr dlgOwner = IntPtr.Zero;
|
||||
public IntPtr instance = IntPtr.Zero;
|
||||
public String filter = null;
|
||||
public String customFilter = null;
|
||||
public int maxCustFilter = 0;
|
||||
public int filterIndex = 0;
|
||||
public String file = null;
|
||||
public int maxFile = 0;
|
||||
public String fileTitle = null;
|
||||
public int maxFileTitle = 0;
|
||||
public String initialDir = null;
|
||||
public String title = null;
|
||||
public int flags = 0;
|
||||
public short fileOffset = 0;
|
||||
public short fileExtension = 0;
|
||||
public String defExt = null;
|
||||
public IntPtr custData = IntPtr.Zero;
|
||||
public IntPtr hook = IntPtr.Zero;
|
||||
public String templateName = null;
|
||||
public IntPtr reservedPtr = IntPtr.Zero;
|
||||
public int reservedInt = 0;
|
||||
public int flagsEx = 0;
|
||||
}
|
||||
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
|
||||
/*
|
||||
public static bool GetOpenFileName1([In, Out] OpenFileName ofn)
|
||||
{
|
||||
return GetOpenFileName(ofn);
|
||||
}
|
||||
*/
|
||||
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
|
||||
|
||||
static string Filter(params string[] filters)
|
||||
{
|
||||
return string.Join("\0", filters) + "\0";
|
||||
}
|
||||
public static string FileDialog(string title, params string[] extensions)
|
||||
{
|
||||
OpenFileName ofn = new OpenFileName();
|
||||
ofn.structSize = Marshal.SizeOf(ofn);
|
||||
|
||||
var filters = new List<string>();
|
||||
filters.Add("All Files"); filters.Add("*.*");
|
||||
foreach(var ext in extensions)
|
||||
{
|
||||
filters.Add(ext); filters.Add("*" + ext);
|
||||
}
|
||||
ofn.filter = Filter(filters.ToArray());
|
||||
ofn.filterIndex = 2;
|
||||
ofn.file = new string(new char[256]);
|
||||
ofn.maxFile = ofn.file.Length;
|
||||
ofn.fileTitle = new string(new char[64]);
|
||||
ofn.maxFileTitle = ofn.fileTitle.Length;
|
||||
ofn.initialDir = UnityEngine.Application.dataPath;
|
||||
ofn.title = title;
|
||||
//ofn.defExt = "PNG";
|
||||
ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR
|
||||
if (!GetOpenFileName(ofn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ofn.file;
|
||||
}
|
||||
public static string SaveDialog(string title, string path)
|
||||
{
|
||||
var extension = Path.GetExtension(path);
|
||||
OpenFileName ofn = new OpenFileName();
|
||||
ofn.structSize = Marshal.SizeOf(ofn);
|
||||
ofn.filter = Filter("All Files", "*.*", extension, "*" + extension);
|
||||
ofn.filterIndex = 2;
|
||||
var chars = new char[256];
|
||||
var it = Path.GetFileName(path).GetEnumerator();
|
||||
for (int i = 0; i < chars.Length && it.MoveNext(); ++i)
|
||||
{
|
||||
chars[i] = it.Current;
|
||||
}
|
||||
ofn.file = new string(chars);
|
||||
ofn.maxFile = ofn.file.Length;
|
||||
ofn.fileTitle = new string(new char[64]);
|
||||
ofn.maxFileTitle = ofn.fileTitle.Length;
|
||||
ofn.initialDir = Path.GetDirectoryName(path);
|
||||
ofn.title = title;
|
||||
//ofn.defExt = "PNG";
|
||||
ofn.flags = 0x00000002 | 0x00000004; // OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
|
||||
if (!GetSaveFileName(ofn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ofn.file;
|
||||
}
|
||||
#endregion
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,142 +1,142 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class RokuroCamera : MonoBehaviour
|
||||
{
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float RotateSpeed = 0.7f;
|
||||
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float GrabSpeed = 0.7f;
|
||||
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float DollySpeed = 1.0f;
|
||||
|
||||
struct PosRot
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
}
|
||||
|
||||
class _Rokuro
|
||||
{
|
||||
public float Yaw;
|
||||
public float Pitch;
|
||||
public float ShiftX;
|
||||
public float ShiftY;
|
||||
public float Distance = 2.0f;
|
||||
|
||||
public void Rotate(float x, float y)
|
||||
{
|
||||
Yaw += x;
|
||||
Pitch -= y;
|
||||
Pitch = Mathf.Clamp(Pitch, -90, 90);
|
||||
}
|
||||
|
||||
public void Grab(float x, float y)
|
||||
{
|
||||
ShiftX += x * Distance;
|
||||
ShiftY += y * Distance;
|
||||
}
|
||||
|
||||
public void Dolly(float delta)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
Distance *= 0.9f;
|
||||
}
|
||||
else if (delta < 0)
|
||||
{
|
||||
Distance *= 1.1f;
|
||||
}
|
||||
}
|
||||
|
||||
public PosRot Calc()
|
||||
{
|
||||
var r = Quaternion.Euler(Pitch, Yaw, 0);
|
||||
return new PosRot
|
||||
{
|
||||
Position = r * new Vector3(-ShiftX, -ShiftY, -Distance),
|
||||
Rotation = r,
|
||||
};
|
||||
}
|
||||
}
|
||||
private _Rokuro _currentCamera = new _Rokuro();
|
||||
|
||||
private List<Coroutine> _activeCoroutines = new List<Coroutine>();
|
||||
private void OnEnable()
|
||||
{
|
||||
// left mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(0, diff =>
|
||||
{
|
||||
_currentCamera.Rotate(diff.x * RotateSpeed, diff.y * RotateSpeed);
|
||||
})));
|
||||
// right mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(1, diff =>
|
||||
{
|
||||
_currentCamera.Rotate(diff.x * RotateSpeed, diff.y * RotateSpeed);
|
||||
})));
|
||||
// middle mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(2, diff =>
|
||||
{
|
||||
_currentCamera.Grab(
|
||||
diff.x * GrabSpeed / Screen.height,
|
||||
diff.y * GrabSpeed / Screen.height
|
||||
);
|
||||
})));
|
||||
// mouse wheel
|
||||
_activeCoroutines.Add(StartCoroutine(MouseScrollOperationCoroutine(diff =>
|
||||
{
|
||||
_currentCamera.Dolly(diff.y * DollySpeed);
|
||||
})));
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
foreach (var coroutine in _activeCoroutines)
|
||||
{
|
||||
StopCoroutine(coroutine);
|
||||
}
|
||||
_activeCoroutines.Clear();
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
var posRot = _currentCamera.Calc();
|
||||
|
||||
transform.localRotation = posRot.Rotation;
|
||||
transform.localPosition = posRot.Position;
|
||||
}
|
||||
private IEnumerator MouseDragOperationCoroutine(int buttonIndex, Action<Vector2> dragOperation)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
while (!Input.GetMouseButtonDown(buttonIndex))
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
var prevPos = Input.mousePosition;
|
||||
while (Input.GetMouseButton(buttonIndex))
|
||||
{
|
||||
var currPos = Input.mousePosition;
|
||||
var diff = currPos - prevPos;
|
||||
dragOperation(diff);
|
||||
|
||||
prevPos = currPos;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private IEnumerator MouseScrollOperationCoroutine(Action<Vector2> scrollOperation)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
scrollOperation(Input.mouseScrollDelta);
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class RokuroCamera : MonoBehaviour
|
||||
{
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float RotateSpeed = 0.7f;
|
||||
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float GrabSpeed = 0.7f;
|
||||
|
||||
[Range(0.1f, 5.0f)]
|
||||
public float DollySpeed = 1.0f;
|
||||
|
||||
struct PosRot
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
}
|
||||
|
||||
class _Rokuro
|
||||
{
|
||||
public float Yaw;
|
||||
public float Pitch;
|
||||
public float ShiftX;
|
||||
public float ShiftY;
|
||||
public float Distance = 2.0f;
|
||||
|
||||
public void Rotate(float x, float y)
|
||||
{
|
||||
Yaw += x;
|
||||
Pitch -= y;
|
||||
Pitch = Mathf.Clamp(Pitch, -90, 90);
|
||||
}
|
||||
|
||||
public void Grab(float x, float y)
|
||||
{
|
||||
ShiftX += x * Distance;
|
||||
ShiftY += y * Distance;
|
||||
}
|
||||
|
||||
public void Dolly(float delta)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
Distance *= 0.9f;
|
||||
}
|
||||
else if (delta < 0)
|
||||
{
|
||||
Distance *= 1.1f;
|
||||
}
|
||||
}
|
||||
|
||||
public PosRot Calc()
|
||||
{
|
||||
var r = Quaternion.Euler(Pitch, Yaw, 0);
|
||||
return new PosRot
|
||||
{
|
||||
Position = r * new Vector3(-ShiftX, -ShiftY, -Distance),
|
||||
Rotation = r,
|
||||
};
|
||||
}
|
||||
}
|
||||
private _Rokuro _currentCamera = new _Rokuro();
|
||||
|
||||
private List<Coroutine> _activeCoroutines = new List<Coroutine>();
|
||||
private void OnEnable()
|
||||
{
|
||||
// left mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(0, diff =>
|
||||
{
|
||||
_currentCamera.Rotate(diff.x * RotateSpeed, diff.y * RotateSpeed);
|
||||
})));
|
||||
// right mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(1, diff =>
|
||||
{
|
||||
_currentCamera.Rotate(diff.x * RotateSpeed, diff.y * RotateSpeed);
|
||||
})));
|
||||
// middle mouse drag
|
||||
_activeCoroutines.Add(StartCoroutine(MouseDragOperationCoroutine(2, diff =>
|
||||
{
|
||||
_currentCamera.Grab(
|
||||
diff.x * GrabSpeed / Screen.height,
|
||||
diff.y * GrabSpeed / Screen.height
|
||||
);
|
||||
})));
|
||||
// mouse wheel
|
||||
_activeCoroutines.Add(StartCoroutine(MouseScrollOperationCoroutine(diff =>
|
||||
{
|
||||
_currentCamera.Dolly(diff.y * DollySpeed);
|
||||
})));
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
foreach (var coroutine in _activeCoroutines)
|
||||
{
|
||||
StopCoroutine(coroutine);
|
||||
}
|
||||
_activeCoroutines.Clear();
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
var posRot = _currentCamera.Calc();
|
||||
|
||||
transform.localRotation = posRot.Rotation;
|
||||
transform.localPosition = posRot.Position;
|
||||
}
|
||||
private IEnumerator MouseDragOperationCoroutine(int buttonIndex, Action<Vector2> dragOperation)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
while (!Input.GetMouseButtonDown(buttonIndex))
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
var prevPos = Input.mousePosition;
|
||||
while (Input.GetMouseButton(buttonIndex))
|
||||
{
|
||||
var currPos = Input.mousePosition;
|
||||
var diff = currPos - prevPos;
|
||||
dragOperation(diff);
|
||||
|
||||
prevPos = currPos;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private IEnumerator MouseScrollOperationCoroutine(Action<Vector2> scrollOperation)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
scrollOperation(Input.mouseScrollDelta);
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class TargetMover : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
float m_radius = 5.0f;
|
||||
|
||||
[SerializeField]
|
||||
float m_angluarVelocity = 40.0f;
|
||||
|
||||
[SerializeField]
|
||||
float m_y = 1.5f;
|
||||
|
||||
[SerializeField]
|
||||
float m_height = 3.0f;
|
||||
|
||||
public IEnumerator Start()
|
||||
{
|
||||
var angle = 0.0f;
|
||||
|
||||
while (true)
|
||||
{
|
||||
angle += m_angluarVelocity * Time.deltaTime * Mathf.Deg2Rad;
|
||||
|
||||
var x = Mathf.Cos(angle) * m_radius;
|
||||
var z = Mathf.Sin(angle) * m_radius;
|
||||
var y = m_y + m_height * Mathf.Cos(angle / 3);
|
||||
|
||||
transform.localPosition = new Vector3(x, y, z);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class TargetMover : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
float m_radius = 5.0f;
|
||||
|
||||
[SerializeField]
|
||||
float m_angluarVelocity = 40.0f;
|
||||
|
||||
[SerializeField]
|
||||
float m_y = 1.5f;
|
||||
|
||||
[SerializeField]
|
||||
float m_height = 3.0f;
|
||||
|
||||
public IEnumerator Start()
|
||||
{
|
||||
var angle = 0.0f;
|
||||
|
||||
while (true)
|
||||
{
|
||||
angle += m_angluarVelocity * Time.deltaTime * Mathf.Deg2Rad;
|
||||
|
||||
var x = Mathf.Cos(angle) * m_radius;
|
||||
var z = Mathf.Sin(angle) * m_radius;
|
||||
var y = m_y + m_height * Mathf.Cos(angle / 3);
|
||||
|
||||
transform.localPosition = new Vector3(x, y, z);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,99 +1,99 @@
|
|||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VRM;
|
||||
|
||||
|
||||
public class VRMRuntimeExporter : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
Button m_loadButton;
|
||||
|
||||
[SerializeField]
|
||||
Button m_exportButton;
|
||||
|
||||
GameObject m_model;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_loadButton.onClick.AddListener(OnLoadClicked);
|
||||
|
||||
m_exportButton.onClick.AddListener(OnExportClicked);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
m_exportButton.interactable = (m_model != null);
|
||||
}
|
||||
|
||||
#region Load
|
||||
void OnLoadClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
|
||||
// metaを取得(todo: thumbnailテクスチャのロード)
|
||||
var meta = context.ReadMeta();
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
context.LoadAsync(_ => OnLoaded(context));
|
||||
}
|
||||
|
||||
void OnLoaded(VRMImporterContext context)
|
||||
{
|
||||
if (m_model != null)
|
||||
{
|
||||
GameObject.Destroy(m_model.gameObject);
|
||||
}
|
||||
|
||||
m_model = context.Root;
|
||||
m_model.transform.rotation = Quaternion.Euler(0, 180, 0);
|
||||
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Export
|
||||
void OnExportClicked()
|
||||
{
|
||||
//#if UNITY_STANDALONE_WIN
|
||||
#if false
|
||||
var path = FileDialogForWindows.SaveDialog("save VRM", Application.dataPath + "/export.vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/../export.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var vrm = VRMExporter.Export(m_model);
|
||||
var bytes = vrm.ToGlbBytes();
|
||||
File.WriteAllBytes(path, bytes);
|
||||
Debug.LogFormat("export to {0}", path);
|
||||
}
|
||||
|
||||
void OnExported(UniGLTF.glTF vrm)
|
||||
{
|
||||
Debug.LogFormat("exported");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VRM;
|
||||
|
||||
|
||||
public class VRMRuntimeExporter : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
Button m_loadButton;
|
||||
|
||||
[SerializeField]
|
||||
Button m_exportButton;
|
||||
|
||||
GameObject m_model;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_loadButton.onClick.AddListener(OnLoadClicked);
|
||||
|
||||
m_exportButton.onClick.AddListener(OnExportClicked);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
m_exportButton.interactable = (m_model != null);
|
||||
}
|
||||
|
||||
#region Load
|
||||
void OnLoadClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
|
||||
// metaを取得(todo: thumbnailテクスチャのロード)
|
||||
var meta = context.ReadMeta();
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
context.LoadAsync(_ => OnLoaded(context));
|
||||
}
|
||||
|
||||
void OnLoaded(VRMImporterContext context)
|
||||
{
|
||||
if (m_model != null)
|
||||
{
|
||||
GameObject.Destroy(m_model.gameObject);
|
||||
}
|
||||
|
||||
m_model = context.Root;
|
||||
m_model.transform.rotation = Quaternion.Euler(0, 180, 0);
|
||||
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Export
|
||||
void OnExportClicked()
|
||||
{
|
||||
//#if UNITY_STANDALONE_WIN
|
||||
#if false
|
||||
var path = FileDialogForWindows.SaveDialog("save VRM", Application.dataPath + "/export.vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/../export.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var vrm = VRMExporter.Export(m_model);
|
||||
var bytes = vrm.ToGlbBytes();
|
||||
File.WriteAllBytes(path, bytes);
|
||||
Debug.LogFormat("export to {0}", path);
|
||||
}
|
||||
|
||||
void OnExported(UniGLTF.glTF vrm)
|
||||
{
|
||||
Debug.LogFormat("exported");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,226 +1,226 @@
|
|||
#pragma warning disable 0414
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VRMRuntimeLoader : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
bool m_loadAsync;
|
||||
|
||||
[SerializeField, Header("GUI")]
|
||||
CanvasManager m_canvas;
|
||||
|
||||
[SerializeField]
|
||||
LookTarget m_faceCamera;
|
||||
|
||||
[SerializeField, Header("loader")]
|
||||
UniHumanoid.HumanPoseTransfer m_source;
|
||||
|
||||
[SerializeField]
|
||||
UniHumanoid.HumanPoseTransfer m_target;
|
||||
|
||||
[SerializeField, Header("runtime")]
|
||||
VRMFirstPerson m_firstPerson;
|
||||
|
||||
VRMBlendShapeProxy m_blendShape;
|
||||
|
||||
void SetupTarget()
|
||||
{
|
||||
if (m_target != null)
|
||||
{
|
||||
m_target.Source = m_source;
|
||||
m_target.SourceType = UniHumanoid.HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_blendShape = m_target.GetComponent<VRMBlendShapeProxy>();
|
||||
|
||||
m_firstPerson = m_target.GetComponent<VRMFirstPerson>();
|
||||
|
||||
var animator = m_target.GetComponent<Animator>();
|
||||
if (animator != null)
|
||||
{
|
||||
m_firstPerson.Setup();
|
||||
|
||||
if (m_faceCamera != null)
|
||||
{
|
||||
m_faceCamera.Target = animator.GetBoneTransform(HumanBodyBones.Head);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
SetupTarget();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (m_canvas == null)
|
||||
{
|
||||
Debug.LogWarning("no canvas");
|
||||
return;
|
||||
}
|
||||
|
||||
m_canvas.LoadVRMButton.onClick.AddListener(LoadVRMClicked);
|
||||
m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked);
|
||||
}
|
||||
|
||||
void LoadVRMClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
|
||||
// metaを取得(todo: thumbnailテクスチャのロード)
|
||||
var meta = context.ReadMeta();
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
if (m_loadAsync)
|
||||
{
|
||||
LoadAsync(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
OnLoaded(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// メタが不要な場合のローダー
|
||||
/// </summary>
|
||||
void LoadVRMClicked_without_meta()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if true
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
if (m_loadAsync)
|
||||
{
|
||||
// ローカルファイルシステムからロードします
|
||||
LoadAsync(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
OnLoaded(context);
|
||||
}
|
||||
|
||||
#else
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
if (m_loadAsync)
|
||||
{
|
||||
// ローカルファイルシステムからロードします
|
||||
VRMImporter.LoadVrmAsync(path, OnLoaded);
|
||||
}
|
||||
else
|
||||
{
|
||||
var root=VRMImporter.LoadFromPath(path);
|
||||
OnLoaded(root);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void LoadAsync(VRMImporterContext context)
|
||||
{
|
||||
#if true
|
||||
var now = Time.time;
|
||||
context.LoadAsync(_ =>
|
||||
{
|
||||
var delta = Time.time - now;
|
||||
Debug.LogFormat("LoadAsync {0:0.0} seconds", delta);
|
||||
OnLoaded(context);
|
||||
});
|
||||
#else
|
||||
// ローカルファイルシステムからロードします
|
||||
VRMImporter.LoadVrmAsync(path, OnLoaded);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LoadBVHClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open BVH", ".bvh");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
LoadBvh(path);
|
||||
}
|
||||
#else
|
||||
LoadBvh(Application.dataPath + "/default.bvh");
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnLoaded(VRMImporterContext context)
|
||||
{
|
||||
var root = context.Root;
|
||||
root.transform.SetParent(transform, false);
|
||||
|
||||
//メッシュを表示します
|
||||
context.ShowMeshes();
|
||||
|
||||
// add motion
|
||||
var humanPoseTransfer = root.AddComponent<UniHumanoid.HumanPoseTransfer>();
|
||||
if (m_target != null)
|
||||
{
|
||||
GameObject.Destroy(m_target.gameObject);
|
||||
}
|
||||
m_target = humanPoseTransfer;
|
||||
SetupTarget();
|
||||
}
|
||||
|
||||
void LoadBvh(string path)
|
||||
{
|
||||
Debug.LogFormat("ImportBvh: {0}", path);
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
|
||||
context.Parse(path);
|
||||
context.Load();
|
||||
|
||||
if (m_source != null)
|
||||
{
|
||||
GameObject.Destroy(m_source.gameObject);
|
||||
}
|
||||
m_source = context.Root.GetComponent<UniHumanoid.HumanPoseTransfer>();
|
||||
|
||||
SetupTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning disable 0414
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class VRMRuntimeLoader : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
bool m_loadAsync;
|
||||
|
||||
[SerializeField, Header("GUI")]
|
||||
CanvasManager m_canvas;
|
||||
|
||||
[SerializeField]
|
||||
LookTarget m_faceCamera;
|
||||
|
||||
[SerializeField, Header("loader")]
|
||||
UniHumanoid.HumanPoseTransfer m_source;
|
||||
|
||||
[SerializeField]
|
||||
UniHumanoid.HumanPoseTransfer m_target;
|
||||
|
||||
[SerializeField, Header("runtime")]
|
||||
VRMFirstPerson m_firstPerson;
|
||||
|
||||
VRMBlendShapeProxy m_blendShape;
|
||||
|
||||
void SetupTarget()
|
||||
{
|
||||
if (m_target != null)
|
||||
{
|
||||
m_target.Source = m_source;
|
||||
m_target.SourceType = UniHumanoid.HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
|
||||
m_blendShape = m_target.GetComponent<VRMBlendShapeProxy>();
|
||||
|
||||
m_firstPerson = m_target.GetComponent<VRMFirstPerson>();
|
||||
|
||||
var animator = m_target.GetComponent<Animator>();
|
||||
if (animator != null)
|
||||
{
|
||||
m_firstPerson.Setup();
|
||||
|
||||
if (m_faceCamera != null)
|
||||
{
|
||||
m_faceCamera.Target = animator.GetBoneTransform(HumanBodyBones.Head);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
SetupTarget();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (m_canvas == null)
|
||||
{
|
||||
Debug.LogWarning("no canvas");
|
||||
return;
|
||||
}
|
||||
|
||||
m_canvas.LoadVRMButton.onClick.AddListener(LoadVRMClicked);
|
||||
m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked);
|
||||
}
|
||||
|
||||
void LoadVRMClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
|
||||
// metaを取得(todo: thumbnailテクスチャのロード)
|
||||
var meta = context.ReadMeta();
|
||||
Debug.LogFormat("meta: title:{0}", meta.Title);
|
||||
|
||||
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
if (m_loadAsync)
|
||||
{
|
||||
LoadAsync(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
OnLoaded(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// メタが不要な場合のローダー
|
||||
/// </summary>
|
||||
void LoadVRMClicked_without_meta()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if true
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
// なんらかの方法でByte列を得た
|
||||
|
||||
var context = new VRMImporterContext();
|
||||
|
||||
// GLB形式でJSONを取得しParseします
|
||||
context.ParseGlb(bytes);
|
||||
|
||||
if (m_loadAsync)
|
||||
{
|
||||
// ローカルファイルシステムからロードします
|
||||
LoadAsync(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Load();
|
||||
OnLoaded(context);
|
||||
}
|
||||
|
||||
#else
|
||||
// ParseしたJSONをシーンオブジェクトに変換していく
|
||||
if (m_loadAsync)
|
||||
{
|
||||
// ローカルファイルシステムからロードします
|
||||
VRMImporter.LoadVrmAsync(path, OnLoaded);
|
||||
}
|
||||
else
|
||||
{
|
||||
var root=VRMImporter.LoadFromPath(path);
|
||||
OnLoaded(root);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void LoadAsync(VRMImporterContext context)
|
||||
{
|
||||
#if true
|
||||
var now = Time.time;
|
||||
context.LoadAsync(_ =>
|
||||
{
|
||||
var delta = Time.time - now;
|
||||
Debug.LogFormat("LoadAsync {0:0.0} seconds", delta);
|
||||
OnLoaded(context);
|
||||
});
|
||||
#else
|
||||
// ローカルファイルシステムからロードします
|
||||
VRMImporter.LoadVrmAsync(path, OnLoaded);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LoadBVHClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open BVH", ".bvh");
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
LoadBvh(path);
|
||||
}
|
||||
#else
|
||||
LoadBvh(Application.dataPath + "/default.bvh");
|
||||
#endif
|
||||
}
|
||||
|
||||
void OnLoaded(VRMImporterContext context)
|
||||
{
|
||||
var root = context.Root;
|
||||
root.transform.SetParent(transform, false);
|
||||
|
||||
//メッシュを表示します
|
||||
context.ShowMeshes();
|
||||
|
||||
// add motion
|
||||
var humanPoseTransfer = root.AddComponent<UniHumanoid.HumanPoseTransfer>();
|
||||
if (m_target != null)
|
||||
{
|
||||
GameObject.Destroy(m_target.gameObject);
|
||||
}
|
||||
m_target = humanPoseTransfer;
|
||||
SetupTarget();
|
||||
}
|
||||
|
||||
void LoadBvh(string path)
|
||||
{
|
||||
Debug.LogFormat("ImportBvh: {0}", path);
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
|
||||
context.Parse(path);
|
||||
context.Load();
|
||||
|
||||
if (m_source != null)
|
||||
{
|
||||
GameObject.Destroy(m_source.gameObject);
|
||||
}
|
||||
m_source = context.Root.GetComponent<UniHumanoid.HumanPoseTransfer>();
|
||||
|
||||
SetupTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,373 +1,373 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class ViewerUI : MonoBehaviour
|
||||
{
|
||||
#region UI
|
||||
[SerializeField]
|
||||
Text m_version;
|
||||
|
||||
[SerializeField]
|
||||
Button m_open;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableLipSync;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableAutoBlink;
|
||||
#endregion
|
||||
|
||||
[SerializeField]
|
||||
HumanPoseTransfer m_src;
|
||||
|
||||
[SerializeField]
|
||||
GameObject m_target;
|
||||
|
||||
[SerializeField]
|
||||
GameObject Root;
|
||||
|
||||
[Serializable]
|
||||
struct TextFields
|
||||
{
|
||||
[SerializeField, Header("Info")]
|
||||
Text m_textModelTitle;
|
||||
[SerializeField]
|
||||
Text m_textModelVersion;
|
||||
[SerializeField]
|
||||
Text m_textModelAuthor;
|
||||
[SerializeField]
|
||||
Text m_textModelContact;
|
||||
[SerializeField]
|
||||
Text m_textModelReference;
|
||||
[SerializeField]
|
||||
RawImage m_thumbnail;
|
||||
|
||||
[SerializeField, Header("CharacterPermission")]
|
||||
Text m_textPermissionAllowed;
|
||||
[SerializeField]
|
||||
Text m_textPermissionViolent;
|
||||
[SerializeField]
|
||||
Text m_textPermissionSexual;
|
||||
[SerializeField]
|
||||
Text m_textPermissionCommercial;
|
||||
[SerializeField]
|
||||
Text m_textPermissionOther;
|
||||
|
||||
[SerializeField, Header("DistributionLicense")]
|
||||
Text m_textDistributionLicense;
|
||||
[SerializeField]
|
||||
Text m_textDistributionOther;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_textModelTitle.text = "";
|
||||
m_textModelVersion.text = "";
|
||||
m_textModelAuthor.text = "";
|
||||
m_textModelContact.text = "";
|
||||
m_textModelReference.text = "";
|
||||
|
||||
m_textPermissionAllowed.text = "";
|
||||
m_textPermissionViolent.text = "";
|
||||
m_textPermissionSexual.text = "";
|
||||
m_textPermissionCommercial.text = "";
|
||||
m_textPermissionOther.text = "";
|
||||
|
||||
m_textDistributionLicense.text = "";
|
||||
m_textDistributionOther.text = "";
|
||||
}
|
||||
|
||||
public void UpdateMeta(VRMImporterContext context)
|
||||
{
|
||||
var meta = context.ReadMeta(true);
|
||||
|
||||
m_textModelTitle.text = meta.Title;
|
||||
m_textModelVersion.text = meta.Version;
|
||||
m_textModelAuthor.text = meta.Author;
|
||||
m_textModelContact.text = meta.ContactInformation;
|
||||
m_textModelReference.text = meta.Reference;
|
||||
|
||||
m_textPermissionAllowed.text = meta.AllowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.ViolentUssage.ToString();
|
||||
m_textPermissionSexual.text = meta.SexualUssage.ToString();
|
||||
m_textPermissionCommercial.text = meta.CommercialUssage.ToString();
|
||||
m_textPermissionOther.text = meta.OtherPermissionUrl;
|
||||
|
||||
m_textDistributionLicense.text = meta.LicenseType.ToString();
|
||||
m_textDistributionOther.text = meta.OtherLicenseUrl;
|
||||
|
||||
m_thumbnail.texture = meta.Thumbnail;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
TextFields m_texts;
|
||||
|
||||
[Serializable]
|
||||
struct UIFields
|
||||
{
|
||||
[SerializeField]
|
||||
Toggle ToggleMotionTPose;
|
||||
|
||||
[SerializeField]
|
||||
Toggle ToggleMotionBVH;
|
||||
|
||||
[SerializeField]
|
||||
ToggleGroup ToggleMotion;
|
||||
|
||||
Toggle m_activeToggleMotion;
|
||||
|
||||
public void UpdateTogle(Action onBvh, Action onTPose)
|
||||
{
|
||||
var value = ToggleMotion.ActiveToggles().FirstOrDefault();
|
||||
if (value == m_activeToggleMotion)
|
||||
return;
|
||||
|
||||
m_activeToggleMotion = value;
|
||||
if (value == ToggleMotionTPose)
|
||||
{
|
||||
onTPose();
|
||||
}
|
||||
else if (value == ToggleMotionBVH)
|
||||
{
|
||||
onBvh();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("motion: no toggle");
|
||||
}
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
UIFields m_ui;
|
||||
|
||||
[SerializeField]
|
||||
HumanPoseClip m_pose;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
var buttons = GameObject.FindObjectsOfType<Button>();
|
||||
m_open = buttons.First(x => x.name == "Open");
|
||||
|
||||
var toggles = GameObject.FindObjectsOfType<Toggle>();
|
||||
m_enableLipSync = toggles.First(x => x.name == "EnableLipSync");
|
||||
m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink");
|
||||
|
||||
var texts = GameObject.FindObjectsOfType<Text>();
|
||||
m_version = texts.First(x => x.name == "Version");
|
||||
|
||||
m_src = GameObject.FindObjectOfType<HumanPoseTransfer>();
|
||||
|
||||
m_target = GameObject.FindObjectOfType<TargetMover>().gameObject;
|
||||
}
|
||||
|
||||
HumanPoseTransfer m_loaded;
|
||||
|
||||
AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
bool EnableLipSyncValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
bool EnableBlinkValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_version.text = string.Format("VRMViewer {0}.{1}",
|
||||
VRMVersion.MAJOR, VRMVersion.MINOR);
|
||||
m_open.onClick.AddListener(OnOpenClicked);
|
||||
|
||||
// load initial bvh
|
||||
LoadMotion(Application.streamingAssetsPath + "/test.txt");
|
||||
|
||||
string[] cmds = System.Environment.GetCommandLineArgs();
|
||||
if (cmds.Length > 1)
|
||||
{
|
||||
LoadModel(cmds[1]);
|
||||
}
|
||||
|
||||
m_texts.Start();
|
||||
}
|
||||
|
||||
private void LoadMotion(string path)
|
||||
{
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
context.Parse(path);
|
||||
context.Load();
|
||||
SetMotion(context.Root.GetComponent<HumanPoseTransfer>());
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (Root != null) Root.SetActive(!Root.activeSelf);
|
||||
}
|
||||
|
||||
m_ui.UpdateTogle(EnableBvh, EnableTPose);
|
||||
}
|
||||
|
||||
void EnableBvh()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableTPose()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.PoseClip = m_pose;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
}
|
||||
|
||||
void OnOpenClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
{
|
||||
case ".gltf":
|
||||
case ".glb":
|
||||
case ".vrm":
|
||||
LoadModel(path);
|
||||
break;
|
||||
|
||||
case ".bvh":
|
||||
LoadMotion(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadModel(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogFormat("{0}", path);
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
{
|
||||
case ".vrm":
|
||||
{
|
||||
var context = new VRMImporterContext();
|
||||
var file = File.ReadAllBytes(path);
|
||||
context.ParseGlb(file);
|
||||
m_texts.UpdateMeta(context);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
break;
|
||||
}
|
||||
|
||||
case ".glb":
|
||||
{
|
||||
var context = new UniGLTF.ImporterContext();
|
||||
var file = File.ReadAllBytes(path);
|
||||
context.ParseGlb(file);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug.LogWarningFormat("unknown file type: {0}", path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetModel(GameObject go)
|
||||
{
|
||||
// cleanup
|
||||
var loaded = m_loaded;
|
||||
m_loaded = null;
|
||||
|
||||
if (loaded != null)
|
||||
{
|
||||
Debug.LogFormat("destroy {0}", loaded);
|
||||
GameObject.Destroy(loaded.gameObject);
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
var lookAt = go.GetComponent<VRMLookAtHead>();
|
||||
if (lookAt != 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>();
|
||||
|
||||
lookAt.Target = m_target.transform;
|
||||
lookAt.UpdateType = UpdateType.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
}
|
||||
|
||||
var animation = go.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetMotion(HumanPoseTransfer src)
|
||||
{
|
||||
m_src = src;
|
||||
src.GetComponent<Renderer>().enabled = false;
|
||||
|
||||
EnableBvh();
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class ViewerUI : MonoBehaviour
|
||||
{
|
||||
#region UI
|
||||
[SerializeField]
|
||||
Text m_version;
|
||||
|
||||
[SerializeField]
|
||||
Button m_open;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableLipSync;
|
||||
|
||||
[SerializeField]
|
||||
Toggle m_enableAutoBlink;
|
||||
#endregion
|
||||
|
||||
[SerializeField]
|
||||
HumanPoseTransfer m_src;
|
||||
|
||||
[SerializeField]
|
||||
GameObject m_target;
|
||||
|
||||
[SerializeField]
|
||||
GameObject Root;
|
||||
|
||||
[Serializable]
|
||||
struct TextFields
|
||||
{
|
||||
[SerializeField, Header("Info")]
|
||||
Text m_textModelTitle;
|
||||
[SerializeField]
|
||||
Text m_textModelVersion;
|
||||
[SerializeField]
|
||||
Text m_textModelAuthor;
|
||||
[SerializeField]
|
||||
Text m_textModelContact;
|
||||
[SerializeField]
|
||||
Text m_textModelReference;
|
||||
[SerializeField]
|
||||
RawImage m_thumbnail;
|
||||
|
||||
[SerializeField, Header("CharacterPermission")]
|
||||
Text m_textPermissionAllowed;
|
||||
[SerializeField]
|
||||
Text m_textPermissionViolent;
|
||||
[SerializeField]
|
||||
Text m_textPermissionSexual;
|
||||
[SerializeField]
|
||||
Text m_textPermissionCommercial;
|
||||
[SerializeField]
|
||||
Text m_textPermissionOther;
|
||||
|
||||
[SerializeField, Header("DistributionLicense")]
|
||||
Text m_textDistributionLicense;
|
||||
[SerializeField]
|
||||
Text m_textDistributionOther;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_textModelTitle.text = "";
|
||||
m_textModelVersion.text = "";
|
||||
m_textModelAuthor.text = "";
|
||||
m_textModelContact.text = "";
|
||||
m_textModelReference.text = "";
|
||||
|
||||
m_textPermissionAllowed.text = "";
|
||||
m_textPermissionViolent.text = "";
|
||||
m_textPermissionSexual.text = "";
|
||||
m_textPermissionCommercial.text = "";
|
||||
m_textPermissionOther.text = "";
|
||||
|
||||
m_textDistributionLicense.text = "";
|
||||
m_textDistributionOther.text = "";
|
||||
}
|
||||
|
||||
public void UpdateMeta(VRMImporterContext context)
|
||||
{
|
||||
var meta = context.ReadMeta(true);
|
||||
|
||||
m_textModelTitle.text = meta.Title;
|
||||
m_textModelVersion.text = meta.Version;
|
||||
m_textModelAuthor.text = meta.Author;
|
||||
m_textModelContact.text = meta.ContactInformation;
|
||||
m_textModelReference.text = meta.Reference;
|
||||
|
||||
m_textPermissionAllowed.text = meta.AllowedUser.ToString();
|
||||
m_textPermissionViolent.text = meta.ViolentUssage.ToString();
|
||||
m_textPermissionSexual.text = meta.SexualUssage.ToString();
|
||||
m_textPermissionCommercial.text = meta.CommercialUssage.ToString();
|
||||
m_textPermissionOther.text = meta.OtherPermissionUrl;
|
||||
|
||||
m_textDistributionLicense.text = meta.LicenseType.ToString();
|
||||
m_textDistributionOther.text = meta.OtherLicenseUrl;
|
||||
|
||||
m_thumbnail.texture = meta.Thumbnail;
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
TextFields m_texts;
|
||||
|
||||
[Serializable]
|
||||
struct UIFields
|
||||
{
|
||||
[SerializeField]
|
||||
Toggle ToggleMotionTPose;
|
||||
|
||||
[SerializeField]
|
||||
Toggle ToggleMotionBVH;
|
||||
|
||||
[SerializeField]
|
||||
ToggleGroup ToggleMotion;
|
||||
|
||||
Toggle m_activeToggleMotion;
|
||||
|
||||
public void UpdateTogle(Action onBvh, Action onTPose)
|
||||
{
|
||||
var value = ToggleMotion.ActiveToggles().FirstOrDefault();
|
||||
if (value == m_activeToggleMotion)
|
||||
return;
|
||||
|
||||
m_activeToggleMotion = value;
|
||||
if (value == ToggleMotionTPose)
|
||||
{
|
||||
onTPose();
|
||||
}
|
||||
else if (value == ToggleMotionBVH)
|
||||
{
|
||||
onBvh();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("motion: no toggle");
|
||||
}
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
UIFields m_ui;
|
||||
|
||||
[SerializeField]
|
||||
HumanPoseClip m_pose;
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
var buttons = GameObject.FindObjectsOfType<Button>();
|
||||
m_open = buttons.First(x => x.name == "Open");
|
||||
|
||||
var toggles = GameObject.FindObjectsOfType<Toggle>();
|
||||
m_enableLipSync = toggles.First(x => x.name == "EnableLipSync");
|
||||
m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink");
|
||||
|
||||
var texts = GameObject.FindObjectsOfType<Text>();
|
||||
m_version = texts.First(x => x.name == "Version");
|
||||
|
||||
m_src = GameObject.FindObjectOfType<HumanPoseTransfer>();
|
||||
|
||||
m_target = GameObject.FindObjectOfType<TargetMover>().gameObject;
|
||||
}
|
||||
|
||||
HumanPoseTransfer m_loaded;
|
||||
|
||||
AIUEO m_lipSync;
|
||||
bool m_enableLipSyncValue;
|
||||
bool EnableLipSyncValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_enableLipSyncValue == value) return;
|
||||
m_enableLipSyncValue = value;
|
||||
if (m_lipSync != null)
|
||||
{
|
||||
m_lipSync.enabled = m_enableLipSyncValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Blinker m_blink;
|
||||
bool m_enableBlinkValue;
|
||||
bool EnableBlinkValue
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_blink == value) return;
|
||||
m_enableBlinkValue = value;
|
||||
if (m_blink != null)
|
||||
{
|
||||
m_blink.enabled = m_enableBlinkValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_version.text = string.Format("VRMViewer {0}.{1}",
|
||||
VRMVersion.MAJOR, VRMVersion.MINOR);
|
||||
m_open.onClick.AddListener(OnOpenClicked);
|
||||
|
||||
// load initial bvh
|
||||
LoadMotion(Application.streamingAssetsPath + "/test.txt");
|
||||
|
||||
string[] cmds = System.Environment.GetCommandLineArgs();
|
||||
if (cmds.Length > 1)
|
||||
{
|
||||
LoadModel(cmds[1]);
|
||||
}
|
||||
|
||||
m_texts.Start();
|
||||
}
|
||||
|
||||
private void LoadMotion(string path)
|
||||
{
|
||||
var context = new UniHumanoid.BvhImporterContext();
|
||||
context.Parse(path);
|
||||
context.Load();
|
||||
SetMotion(context.Root.GetComponent<HumanPoseTransfer>());
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
EnableLipSyncValue = m_enableLipSync.isOn;
|
||||
EnableBlinkValue = m_enableAutoBlink.isOn;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (Root != null) Root.SetActive(!Root.activeSelf);
|
||||
}
|
||||
|
||||
m_ui.UpdateTogle(EnableBvh, EnableTPose);
|
||||
}
|
||||
|
||||
void EnableBvh()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.Source = m_src;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableTPose()
|
||||
{
|
||||
if (m_loaded != null)
|
||||
{
|
||||
m_loaded.PoseClip = m_pose;
|
||||
m_loaded.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip;
|
||||
}
|
||||
}
|
||||
|
||||
void OnOpenClicked()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN
|
||||
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
|
||||
#else
|
||||
var path = Application.dataPath + "/default.vrm";
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
{
|
||||
case ".gltf":
|
||||
case ".glb":
|
||||
case ".vrm":
|
||||
LoadModel(path);
|
||||
break;
|
||||
|
||||
case ".bvh":
|
||||
LoadMotion(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadModel(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogFormat("{0}", path);
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
switch (ext)
|
||||
{
|
||||
case ".vrm":
|
||||
{
|
||||
var context = new VRMImporterContext();
|
||||
var file = File.ReadAllBytes(path);
|
||||
context.ParseGlb(file);
|
||||
m_texts.UpdateMeta(context);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
break;
|
||||
}
|
||||
|
||||
case ".glb":
|
||||
{
|
||||
var context = new UniGLTF.ImporterContext();
|
||||
var file = File.ReadAllBytes(path);
|
||||
context.ParseGlb(file);
|
||||
context.Load();
|
||||
context.ShowMeshes();
|
||||
context.EnableUpdateWhenOffscreen();
|
||||
context.ShowMeshes();
|
||||
SetModel(context.Root);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug.LogWarningFormat("unknown file type: {0}", path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetModel(GameObject go)
|
||||
{
|
||||
// cleanup
|
||||
var loaded = m_loaded;
|
||||
m_loaded = null;
|
||||
|
||||
if (loaded != null)
|
||||
{
|
||||
Debug.LogFormat("destroy {0}", loaded);
|
||||
GameObject.Destroy(loaded.gameObject);
|
||||
}
|
||||
|
||||
if (go != null)
|
||||
{
|
||||
var lookAt = go.GetComponent<VRMLookAtHead>();
|
||||
if (lookAt != 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>();
|
||||
|
||||
lookAt.Target = m_target.transform;
|
||||
lookAt.UpdateType = UpdateType.LateUpdate; // after HumanPoseTransfer's setPose
|
||||
}
|
||||
|
||||
var animation = go.GetComponent<Animation>();
|
||||
if (animation && animation.clip != null)
|
||||
{
|
||||
animation.Play(animation.clip.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetMotion(HumanPoseTransfer src)
|
||||
{
|
||||
m_src = src;
|
||||
src.GetComponent<Renderer>().enabled = false;
|
||||
|
||||
EnableBvh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user