add VRM10FirstPersonSample

This commit is contained in:
ousttrue
2021-09-09 17:16:55 +09:00
parent 41c3bd64f9
commit df59ac1979
13 changed files with 2283 additions and 0 deletions

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 056ca4a0e47b8b5408a1c557768e188b
timeCreated: 1520832729
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace UniVRM10.FirstPersonSample
{
public class VRM10CanvasManager : 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");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58bd4ef7b3a863142ae9960c21106ba3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
#if UNITY_STANDALONE_WIN
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
#endif
namespace UniVRM10.FirstPersonSample
{
public static class VRM10FileDialogForWindows
{
#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
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e637d7baec8ac742bcb7709db745193
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using UnityEngine;
using UniGLTF;
namespace UniVRM10
{
public class VRM10LookTarget : MonoBehaviour
{
[SerializeField]
public Transform Target;
[SerializeField]
Vector3 m_offset = new Vector3(0, 0.05f, 0);
[SerializeField, Range(0, 3.0f)]
float m_distance = 0.7f;
public VRM10OffsetOnTransform m_offsetTransform;
void Update()
{
if (Target != m_offsetTransform.Transform)
{
m_offsetTransform = VRM10OffsetOnTransform.Create(Target);
}
var target = m_offsetTransform.Transform;
if (target != null)
{
var targetPosition = target.position + m_offset;
transform.position = targetPosition + (m_offsetTransform.WorldMatrix.ExtractRotation() * Vector3.forward) * m_distance;
transform.LookAt(targetPosition);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b74319fb726e30c4ca99bd741af8bd3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
using System;
using UnityEngine;
namespace UniVRM10
{
[Serializable]
public struct VRM10OffsetOnTransform
{
public Transform Transform;
public Matrix4x4 OffsetRotation;
public Matrix4x4 WorldMatrix
{
get
{
if (Transform == null) return Matrix4x4.identity;
return Transform.localToWorldMatrix * OffsetRotation;
}
}
public Vector3 WorldForward
{
get
{
var m = WorldMatrix;
return m.GetColumn(2); // zaxis
}
}
Matrix4x4 m_initialLocalMatrix;
public void Setup()
{
if (Transform == null) return;
m_initialLocalMatrix = Transform.parent.worldToLocalMatrix * Transform.localToWorldMatrix;
}
public Matrix4x4 InitialWorldMatrix
{
get
{
return Transform.parent.localToWorldMatrix * m_initialLocalMatrix;
}
}
public static VRM10OffsetOnTransform Create(Transform transform)
{
var coordinate = new VRM10OffsetOnTransform
{
Transform = transform
};
if (transform != null)
{
coordinate.OffsetRotation = transform.worldToLocalMatrix.RotationToWorldAxis();
}
return coordinate;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 463fb7b24167d6a49a43bbcc4dfd42b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,142 @@
#pragma warning disable 0414
using System.IO;
using System.Threading.Tasks;
using UniGLTF;
using UnityEngine;
namespace UniVRM10.FirstPersonSample
{
public class VRM10RuntimeLoader : MonoBehaviour
{
[SerializeField, Header("GUI")]
VRM10CanvasManager m_canvas = default;
[SerializeField]
VRM10LookTarget m_faceCamera = default;
[SerializeField, Header("loader")]
UniHumanoid.HumanPoseTransfer m_source;
[SerializeField]
UniHumanoid.HumanPoseTransfer m_target;
[SerializeField, Header("runtime")]
VRM10Controller m_firstPerson;
async Task SetupTargetAsync(UniHumanoid.HumanPoseTransfer m_target, bool visible)
{
if (m_target != null)
{
m_target.Source = m_source;
m_target.SourceType = UniHumanoid.HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
m_firstPerson = m_target.GetComponent<VRM10Controller>();
var animator = m_target.GetComponent<Animator>();
if (animator != null)
{
await m_firstPerson.Vrm.FirstPerson.SetupAsync(m_firstPerson.gameObject, visible);
if (m_faceCamera != null)
{
m_faceCamera.Target = animator.GetBoneTransform(HumanBodyBones.Head);
}
}
}
}
private void Start()
{
if (m_canvas == null)
{
Debug.LogWarning("no canvas");
return;
}
m_canvas.LoadVRMButton.onClick.AddListener(LoadVRMClicked);
m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked);
}
async void LoadVRMClicked()
{
#if UNITY_STANDALONE_WIN
var path = VRM10FileDialogForWindows.FileDialog("open VRM", ".vrm");
#elif UNITY_EDITOR
var path = UnityEditor.EditorUtility.OpenFilePanel("Open VRM", "", "vrm");
#else
var path = Application.dataPath + "/default.vrm";
#endif
if (string.IsNullOrEmpty(path))
{
return;
}
// GLB形式でJSONを取得しParseします
// VRM extension を parse します
var data = new GlbFileParser(path).Parse();
Vrm10Data.TryParseOrMigrate(data, true, out Vrm10Data vrm);
using (var context = new Vrm10Importer(vrm))
{
// metaを取得(todo: thumbnailテクスチャのロード)
var meta = vrm.VrmExtension.Meta;
Debug.LogFormat("meta: title:{0}", meta.Name);
// ParseしたJSONをシーンオブジェクトに変換していく
var loaded = await context.LoadAsync();
var root = loaded.gameObject;
root.transform.SetParent(transform, false);
// add motion
var humanPoseTransfer = root.AddComponent<UniHumanoid.HumanPoseTransfer>();
if (m_target != null)
{
GameObject.Destroy(m_target.gameObject);
}
m_target = humanPoseTransfer;
await SetupTargetAsync(m_target, visible: false);
//メッシュを表示します
// loaded.ShowMeshes();
}
}
void LoadBVHClicked()
{
#if UNITY_STANDALONE_WIN
var path = VRM10FileDialogForWindows.FileDialog("open BVH", ".bvh");
if (!string.IsNullOrEmpty(path))
{
LoadBvh(path);
}
#elif UNITY_EDITOR
var path = UnityEditor.EditorUtility.OpenFilePanel("Open BVH", "", "bvh");
if (!string.IsNullOrEmpty(path))
{
LoadBvh(path);
}
#else
LoadBvh(Application.dataPath + "/default.bvh");
#endif
}
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>();
var task = SetupTargetAsync(m_target, true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd151410f22d0f6409cf4b17c03a3c6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: