diff --git a/Assets/VRM.Samples/Scripts/AIUEO.cs.meta b/Assets/VRM.Samples/Scripts/AIUEO.cs.meta index d245454c5..490d459d2 100644 --- a/Assets/VRM.Samples/Scripts/AIUEO.cs.meta +++ b/Assets/VRM.Samples/Scripts/AIUEO.cs.meta @@ -1,7 +1,5 @@ fileFormatVersion: 2 -guid: b62ca4f3096cada41938f18e4a02d8dc -timeCreated: 1517463794 -licenseType: Free +guid: e7d971d3cc4439c4ba3f3ae4072cf82d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/VRM.Samples/Scripts/TargetMover.cs.meta b/Assets/VRM.Samples/Scripts/TargetMover.cs.meta index 21a35758b..acb77af96 100644 --- a/Assets/VRM.Samples/Scripts/TargetMover.cs.meta +++ b/Assets/VRM.Samples/Scripts/TargetMover.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 -guid: c04054aea7a18b642b0a4905e808604e -timeCreated: 1524045545 -licenseType: Free +guid: 93a55f745733f794b963f9eb00d0c0af MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/VRM10.Samples.meta b/Assets/VRM10.Samples.meta new file mode 100644 index 000000000..d046d8335 --- /dev/null +++ b/Assets/VRM10.Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c5c0de34a00d309409bfc1d534e2610a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime.meta b/Assets/VRM10.Samples/Runtime.meta new file mode 100644 index 000000000..ece33ccbc --- /dev/null +++ b/Assets/VRM10.Samples/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a00625daa13c4a34ba99d9e0c80c0ad6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime/AIUEO.cs b/Assets/VRM10.Samples/Runtime/AIUEO.cs new file mode 100644 index 000000000..4f81259e7 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/AIUEO.cs @@ -0,0 +1,73 @@ +using System.Collections; +using UnityEngine; + + +namespace UniVRM10.Samples +{ + public class AIUEO : MonoBehaviour + { + [SerializeField] + public VRM10Controller VRM; + private void Reset() + { + VRM = GetComponent(); + } + + Coroutine m_coroutine; + + [SerializeField] + float m_wait = 0.5f; + + private void Awake() + { + if (VRM == null) + { + VRM = GetComponent(); + } + } + + IEnumerator RoutineNest(VrmLib.ExpressionPreset preset, float velocity, float wait) + { + for (var value = 0.0f; value <= 1.0f; value += velocity) + { + VRM.Expression.Accumulator.SetPresetValue(preset, value); + yield return null; + } + VRM.Expression.Accumulator.SetPresetValue(preset, 1.0f); + yield return new WaitForSeconds(wait); + for (var value = 1.0f; value >= 0; value -= velocity) + { + VRM.Expression.Accumulator.SetPresetValue(preset, value); + yield return null; + } + VRM.Expression.Accumulator.SetPresetValue(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(VrmLib.ExpressionPreset.Aa, velocity, m_wait); + yield return RoutineNest(VrmLib.ExpressionPreset.Ih, velocity, m_wait); + yield return RoutineNest(VrmLib.ExpressionPreset.Ou, velocity, m_wait); + yield return RoutineNest(VrmLib.ExpressionPreset.Ee, velocity, m_wait); + yield return RoutineNest(VrmLib.ExpressionPreset.Oh, velocity, m_wait); + } + } + + private void OnEnable() + { + m_coroutine = StartCoroutine(Routine()); + } + + private void OnDisable() + { + StopCoroutine(m_coroutine); + } + } +} diff --git a/Assets/VRM10.Samples/Runtime/AIUEO.cs.meta b/Assets/VRM10.Samples/Runtime/AIUEO.cs.meta new file mode 100644 index 000000000..d245454c5 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/AIUEO.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b62ca4f3096cada41938f18e4a02d8dc +timeCreated: 1517463794 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime/Blinker.cs b/Assets/VRM10.Samples/Runtime/Blinker.cs new file mode 100644 index 000000000..0ff3b7041 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/Blinker.cs @@ -0,0 +1,116 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.Serialization; + +namespace UniVRM10.Samples +{ + /// + /// VRMBlendShapeProxy によるランダムに瞬きするサンプル。 + /// VRMBlendShapeProxy のある GameObject にアタッチする。 + /// + public class Blinker : MonoBehaviour + { + VRM10Controller m_controller; + + [FormerlySerializedAs("m_interVal")] + [SerializeField] + public float Interval = 5.0f; + + [FormerlySerializedAs("m_closingTime")] + [SerializeField] + public float ClosingTime = 0.06f; + + [FormerlySerializedAs("m_openingSeconds")] + [SerializeField] + public float OpeningSeconds = 0.03f; + + [FormerlySerializedAs("m_closeSeconds")] + [SerializeField] + public float CloseSeconds = 0.1f; + + Coroutine m_coroutine; + + float m_nextRequest; + bool m_request; + public bool Request + { + get { return m_request; } + set + { + if (Time.time < m_nextRequest) + { + return; + } + m_request = value; + m_nextRequest = Time.time + 1.0f; + } + } + + IEnumerator BlinkRoutine() + { + while (true) + { + var waitTime = Time.time + Random.value * Interval; + while (waitTime > Time.time) + { + if (Request) + { + m_request = false; + break; + } + yield return null; + } + + // close + var value = 0.0f; + var closeSpeed = 1.0f / CloseSeconds; + while (true) + { + value += Time.deltaTime * closeSpeed; + if (value >= 1.0f) + { + break; + } + + m_controller.Expression.Accumulator.SetPresetValue(VrmLib.ExpressionPreset.Blink, value); + yield return null; + } + m_controller.Expression.Accumulator.SetPresetValue(VrmLib.ExpressionPreset.Blink, 1.0f); + + // wait... + yield return new WaitForSeconds(ClosingTime); + + // open + value = 1.0f; + var openSpeed = 1.0f / OpeningSeconds; + while (true) + { + value -= Time.deltaTime * openSpeed; + if (value < 0) + { + break; + } + + m_controller.Expression.Accumulator.SetPresetValue(VrmLib.ExpressionPreset.Blink, value); + yield return null; + } + m_controller.Expression.Accumulator.SetPresetValue(VrmLib.ExpressionPreset.Blink, 0); + } + } + + private void OnEnable() + { + m_controller = GetComponent(); + m_coroutine = StartCoroutine(BlinkRoutine()); + } + + private void OnDisable() + { + if (m_coroutine != null) + { + StopCoroutine(m_coroutine); + m_coroutine = null; + } + } + } +} diff --git a/Assets/VRM10.Samples/Runtime/Blinker.cs.meta b/Assets/VRM10.Samples/Runtime/Blinker.cs.meta new file mode 100644 index 000000000..8d5a197f1 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/Blinker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 240708f0d7a638c469928ca5403ecb03 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs b/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs new file mode 100644 index 000000000..62968f62a --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs @@ -0,0 +1,118 @@ +#if UNITY_STANDALONE_WIN +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +#endif + + +namespace UniVRM10.Samples +{ + 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(); + 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 + } +} diff --git a/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs.meta b/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs.meta new file mode 100644 index 000000000..5e250cd57 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/FileDialogForWindows.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa442bd5bf48b664a9cf7aa4d522c4a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime/TargetMover.cs b/Assets/VRM10.Samples/Runtime/TargetMover.cs new file mode 100644 index 000000000..41182c6f4 --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/TargetMover.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace UniVRM10.Samples +{ + public class TargetMover : MonoBehaviour + { + [SerializeField] + float m_radius = 5.0f; + + [SerializeField] + float m_angularVelocity = 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_angularVelocity * 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; + } + } + } +} diff --git a/Assets/VRM10.Samples/Runtime/TargetMover.cs.meta b/Assets/VRM10.Samples/Runtime/TargetMover.cs.meta new file mode 100644 index 000000000..21a35758b --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/TargetMover.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c04054aea7a18b642b0a4905e808604e +timeCreated: 1524045545 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10.Samples/Runtime/ViewerUI.cs b/Assets/VRM10.Samples/Runtime/ViewerUI.cs new file mode 100644 index 000000000..34762f6fe --- /dev/null +++ b/Assets/VRM10.Samples/Runtime/ViewerUI.cs @@ -0,0 +1,410 @@ +using System; +using System.IO; +using System.Linq; +using UniHumanoid; +using UnityEngine; +using UnityEngine.UI; + + +namespace UniVRM10.Samples +{ + public class ViewerUI : MonoBehaviour + { + #region UI + [SerializeField] + Text m_version = default; + + [SerializeField] + Button m_open = default; + + [SerializeField] + Toggle m_enableLipSync = default; + + [SerializeField] + Toggle m_enableAutoBlink = default; + #endregion + + [SerializeField] + HumanPoseTransfer m_src = default; + + [SerializeField] + GameObject m_target = default; + + [SerializeField] + GameObject Root = default; + + [Serializable] + class TextFields + { + [SerializeField, Header("Info")] + Text m_textModelTitle = default; + [SerializeField] + Text m_textModelVersion = default; + [SerializeField] + Text m_textModelAuthor = default; + [SerializeField] + Text m_textModelContact = default; + [SerializeField] + Text m_textModelReference = default; + [SerializeField] + RawImage m_thumbnail = default; + + [SerializeField, Header("CharacterPermission")] + Text m_textPermissionAllowed = default; + [SerializeField] + Text m_textPermissionViolent = default; + [SerializeField] + Text m_textPermissionSexual = default; + [SerializeField] + Text m_textPermissionCommercial = default; + [SerializeField] + Text m_textPermissionOther = default; + + [SerializeField, Header("DistributionLicense")] + Text m_textDistributionLicense = default; + [SerializeField] + Text m_textDistributionOther = default; + + 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(VRM10Controller context) + { + // var meta = context.ReadMeta(true); + var meta = context.Meta; + + m_textModelTitle.text = meta.Name; + m_textModelVersion.text = meta.Version; + m_textModelAuthor.text = meta.Authors[0]; + m_textModelContact.text = meta.ContactInformation; + m_textModelReference.text = meta.Reference; + + m_textPermissionAllowed.text = meta.AllowedUser.ToString(); + m_textPermissionViolent.text = meta.ViolentUsage.ToString(); + m_textPermissionSexual.text = meta.SexualUsage.ToString(); + m_textPermissionCommercial.text = meta.CommercialUsage.ToString(); + m_textPermissionOther.text = meta.OtherPermissionUrl; + + m_textDistributionLicense.text = meta.ModificationLicense.ToString(); + m_textDistributionOther.text = meta.OtherLicenseUrl; + + m_thumbnail.texture = meta.Thumbnail; + } + } + [SerializeField] + TextFields m_texts = default; + + [Serializable] + class UIFields + { + [SerializeField] + Toggle ToggleMotionTPose = default; + + [SerializeField] + Toggle ToggleMotionBVH = default; + + [SerializeField] + ToggleGroup ToggleMotion = default; + + Toggle m_activeToggleMotion = default; + + public void UpdateToggle(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 = default; + + [SerializeField] + HumanPoseClip m_pose = default; + + private void Reset() + { + var buttons = GameObject.FindObjectsOfType