version 2.0.0

This commit is contained in:
srl87
2023-09-14 18:17:47 +08:00
parent 13e9d00b37
commit db9f64d8eb
953 changed files with 125887 additions and 21229 deletions

View File

@@ -1,80 +0,0 @@
# **VIVE OpenXR Plugin - Windows** For Unity - v1.0.13
Copyright HTC Corporation. All Rights Reserved.
**VIVE OpenXR Plugin - Windows**: This plugin provides support for openxr based on the following specifications.
- [Vive Facial Tracking](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_facial_tracking)
- [Vive Cosmos Controller](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_vive_cosmos_controller_interaction)
- [Scene Understanding](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_scene_understanding)
- [Hand Tracking](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hand_tracking)
- [Vive Focus3 Controller](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_vive_focus3_controller_interaction)
- [Hand Interaction](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_hand_interaction)
- [Palm pose](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_palm_pose)
---
## Changes for v1.0.13 - 2023/06/26
- Fix problem that "OpenXR.Input.PoseControl" and "OpenXR.Input.Pose" are deprecated after OpenXR Plugin 1.6.0.
1. When **USE_INPUT_SYSTEM_POSE_CONTROL** is defined, switch to use InputSystem.XR.PoseControl; otherwise, use OpenXR.Input.PoseControl for backward compatibility.
2. When **USE_INPUT_SYSTEM_POSE_CONTROL** is defined, switch to use InputSystem.XR.PoseState; otherwise, use OpenXR.Input.Pose for backward compatibility.
## Changes for v1.0.12 - 2023/06/02
- Remove Eye gaze sample.It is recommended to use the Controller sample provided by the Unity OpenXR Plugin to test eye gaze.
## Changes for v1.0.11 - 2023/02/16
- Add openxr XR_EXT_palm_pose support for Vive Focus3 controller and Vive Cosmos controller.
- Add Hand Interaction extension support.
- Add hand interaction demo in hand tracking sample.
## Changes for v1.0.10 - 2023/01/13
- Add eye gaze sample.
## Changes for v1.0.9 - 2022/11/10
- Fix the dependency issue with OpenXR plugin.
## Changes for v1.0.8 - 2022/10/11
- Update the package name from **Vive Wave OpenXR Plugin - Windows** to **VIVE OpenXR Plugin - Windows**.
- Fixed problem that blendshapes and input element columns of facial tracking sample not aligned correctly in Unity Inspector.
- Fix haptic problem for cosmos controller profile.
- Add Focus3 controller extension support.
## Changes for v1.0.7 - 2022/09/26
- Fixed function type conversion problem when using handtracking feature with other OpenXR features at the same time.
## Changes for v1.0.6 - 2022/09/15
### Vive Hand Tracking
- Fixed delay problem when locating controller with HandTracking extension.
## Changes for v1.0.5 - 2022/06/24
- Update documentation links for (1) Vive Facial Tracking (2) Vive Cosmos Controller (3) Scene Understanding (4) Hand Tracking.
- Refine plugin and sample for (1) Vive Facial Tracking (2) Hand Tracking.
### Vive Hand Tracking
- Implement extension XR_EXT_hand_joints_motion_range for Hand tracking.
- Fixed incorrect joint rotation.
### Vive Facial Tracking
- Fixed incorrect eye gaze direction for sample.
## Changes for v1.0.4 - 2022/4/28:
- Update the package name from **Vive OpenXR Plugin** to **VIVE Wave OpenXR Plugin - Windows**.
- Fixed missing material for Hand Tracking sample.
- Fixed Hand tracking sample crashed issue.
- Add 3D HandTracking Sample.
## Changes for v1.0.3 - 2022/4/08:
- Refactor Hand Tracking sample.
- Fixed build error related to Scene Understanding plugin.
## Changes for v1.0.2 - 2022/3/23:
- Add support for openxr hand tracking extension.
## Changes for v1.0.1 - 2022/2/10:
### Vive Cosmos Controller
- Correct the input path of menu key.
### Scene Understanding
- Move Mesh subsystem from plugin part to sample code.
## Changes for v1.0.0 - 2021/1/06:
* This is the first release of Vive OpenXR Unity Plugin.

View File

@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 28769a4eba0d8bf448df06f6edc80599
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: aae4484d37f3dc949851ce06e791456e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,313 @@
// Copyright HTC Corporation All Rights Reserved.
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Xml;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEditor.PackageManager;
using UnityEditor.XR.OpenXR.Features;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.OpenXR.Features;
using VIVE.OpenXR.Hand;
using VIVE.OpenXR.Tracker;
// Reference to Unity's OpenXR package
namespace VIVE.OpenXR.Editor
{
internal class ModifyAndroidManifest : OpenXRFeatureBuildHooks
{
public override int callbackOrder => 1;
public override Type featureType => typeof(VIVEFocus3Feature);
protected override void OnPreprocessBuildExt(BuildReport report)
{
}
private static string _manifestPath;
protected override void OnPostGenerateGradleAndroidProjectExt(string path)
{
_manifestPath = GetManifestPath(path);
var androidManifest = new AndroidManifest(_manifestPath);
//androidManifest.AddVIVECategory();
androidManifest.AddViveSDKVersion();
androidManifest.AddUnityVersion();
androidManifest.AddOpenXRPermission();
androidManifest.AddOpenXRFeatures();
androidManifest.Save();
}
protected override void OnPostprocessBuildExt(BuildReport report)
{
if (File.Exists(_manifestPath))
File.Delete(_manifestPath);
}
private string _manifestFilePath;
private string GetManifestPath(string basePath)
{
if (!string.IsNullOrEmpty(_manifestFilePath)) return _manifestFilePath;
var pathBuilder = new StringBuilder(basePath);
pathBuilder.Append(Path.DirectorySeparatorChar).Append("src");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("main");
pathBuilder.Append(Path.DirectorySeparatorChar).Append("AndroidManifest.xml");
_manifestFilePath = pathBuilder.ToString();
return _manifestFilePath;
}
private class AndroidXmlDocument : XmlDocument
{
private string m_Path;
protected XmlNamespaceManager nsMgr;
public readonly string AndroidXmlNamespace = "http://schemas.android.com/apk/res/android";
public AndroidXmlDocument(string path)
{
m_Path = path;
using (var reader = new XmlTextReader(m_Path))
{
reader.Read();
Load(reader);
}
nsMgr = new XmlNamespaceManager(NameTable);
nsMgr.AddNamespace("android", AndroidXmlNamespace);
}
public string Save()
{
return SaveAs(m_Path);
}
public string SaveAs(string path)
{
using (var writer = new XmlTextWriter(path, new UTF8Encoding(false)))
{
writer.Formatting = Formatting.Indented;
Save(writer);
}
return path;
}
}
[InitializeOnLoad]
public static class CheckIfSimultaneousInteractionEnabled
{
const string LOG_TAG = "CheckIfSimultaneousInteractionEnabled ";
static StringBuilder m_sb = null;
static StringBuilder sb
{
get
{
if (m_sb == null) { m_sb = new StringBuilder(); }
return m_sb;
}
}
static void DEBUG(StringBuilder msg) { Debug.Log(msg); }
internal const string MENU_NAME = "VIVE/Interaction Mode/Enable Simultaneous Interaction";
private static bool m_IsEnabled = false;
public static bool IsEnabled { get { return m_IsEnabled; } }
static CheckIfSimultaneousInteractionEnabled()
{
m_IsEnabled = EditorPrefs.GetBool(MENU_NAME, false);
/// Delaying until first editor tick so that the menu
/// will be populated before setting check state, and
/// re-apply correct action
EditorApplication.delayCall += () =>
{
PerformAction(m_IsEnabled);
};
}
[MenuItem(MENU_NAME, priority = 601)]
private static void ToggleAction()
{
/// Toggling action
PerformAction(!m_IsEnabled);
}
public static void PerformAction(bool enabled)
{
/// Set checkmark on menu item
Menu.SetChecked(MENU_NAME, enabled);
/// Saving editor state
EditorPrefs.SetBool(MENU_NAME, enabled);
m_IsEnabled = enabled;
sb.Clear().Append(LOG_TAG).Append(m_IsEnabled ? "Enable " : "Disable ").Append("Simultaneous Interaction."); DEBUG(sb);
}
[MenuItem(MENU_NAME, validate = true, priority = 601)]
public static bool ValidateEnabled()
{
Menu.SetChecked(MENU_NAME, m_IsEnabled);
return true;
}
}
private class AndroidManifest : AndroidXmlDocument
{
private readonly XmlElement IntetnFilterElement;
private readonly XmlElement ManifestElement;
private readonly XmlElement ApplicationElement;
public AndroidManifest(string path) : base(path)
{
IntetnFilterElement = SelectSingleNode("/manifest/application/activity/intent-filter") as XmlElement;
ManifestElement = SelectSingleNode("/manifest") as XmlElement;
ApplicationElement = SelectSingleNode("/manifest/application") as XmlElement;
}
private XmlAttribute CreateAndroidAttribute(string key, string value)
{
XmlAttribute attr = CreateAttribute("android", key, AndroidXmlNamespace);
attr.Value = value;
return attr;
}
private const string FAKE_VERSION = "0.0.0";
private static string SearchPackageVersion(string packageName)
{
var listRequest = Client.List(true);
do
{
if (listRequest.IsCompleted)
{
if (listRequest.Result == null)
{
Debug.Log("List result: is empty");
return FAKE_VERSION;
}
foreach (var pi in listRequest.Result)
{
//Debug.Log("List has: " + pi.name + " == " + packageName);
if (pi.name == packageName)
{
Debug.Log("Found " + packageName);
return pi.version;
}
}
break;
}
Thread.Sleep(100);
} while (true);
return FAKE_VERSION;
}
internal void AddViveSDKVersion()
{
var newUsesFeature = CreateElement("meta-data");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "com.htc.ViveOpenXR.SdkVersion"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("value", SearchPackageVersion("com.htc.upm.vive.openxr")));
ApplicationElement.AppendChild(newUsesFeature);
}
internal void AddUnityVersion()
{
var newUsesFeature = CreateElement("meta-data");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "com.htc.vr.content.UnityVersion"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("value", Application.unityVersion));
ApplicationElement.AppendChild(newUsesFeature);
}
internal void AddVIVECategory()
{
var md = IntetnFilterElement.AppendChild(CreateElement("category"));
md.Attributes.Append(CreateAndroidAttribute("name", "com.htc.intent.category.VRAPP"));
}
internal void AddOpenXRPermission()
{
var md = ManifestElement.AppendChild(CreateElement("uses-permission"));
md.Attributes.Append(CreateAndroidAttribute("name", "org.khronos.openxr.permission.OPENXR"));
md = ManifestElement.AppendChild(CreateElement("uses-permission"));
md.Attributes.Append(CreateAndroidAttribute("name", "org.khronos.openxr.permission.OPENXR_SYSTEM"));
var md2 = IntetnFilterElement.AppendChild(CreateElement("category"));
md2.Attributes.Append(CreateAndroidAttribute("name", "org.khronos.openxr.intent.category.IMMERSIVE_HMD"));
}
internal void AddOpenXRFeatures()
{
bool enableViveWristTracker = false;
bool enableViveHandTracking = false;
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
if (null == settings)
return;
foreach (var feature in settings.GetFeatures<OpenXRInteractionFeature>())
{
if (feature is ViveWristTracker)
{
enableViveWristTracker = feature.enabled;
break;
}
}
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
{
if (feature is ViveHandTracking)
{
enableViveHandTracking = feature.enabled;
break; ;
}
}
//Debug.Log("enableViveWristTracker " + enableViveWristTracker);
if (enableViveWristTracker)
{
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.handtracking"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.tracker"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
}
else if (enableViveHandTracking)
{
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.handtracking"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
}
if (CheckIfSimultaneousInteractionEnabled.IsEnabled)
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.simultaneous_interaction"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b9da6a2c254e9354891b5ab88cd630f0
guid: cd029ee7a3204f446b0def5eafc0a380
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 3af3c139ab2eee9498a484a154cad9af
guid: ddf1278db13678e45b960b274d526b39
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 686c57b9d62a14c47b8353ea34d46bb3
guid: 213dee666ce1d064bac61bf4164523d9
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,539 @@
// "VIVE SDK
// © 2020 HTC Corporation. All Rights Reserved.
//
// Unless otherwise required by copyright law and practice,
// upon the execution of HTC SDK license agreement,
// HTC grants you access to and use of the VIVE SDK(s).
// You shall fully comply with all of HTCs SDK license agreement terms and
// conditions signed by you and all SDK and API requirements,
// specifications, and documentation provided by HTC to You."
using UnityEngine;
#if UNITY_EDITOR
namespace VIVE.OpenXR.CompositionLayer.Editor
{
#region Composition Layer Editor
using UnityEditor;
using UnityEditor.SceneManagement;
using VIVE.OpenXR.CompositionLayer;
using UnityEditor.XR.OpenXR.Features;
[CustomEditor(typeof(CompositionLayer))]
public class CompositionLayerEditor : Editor
{
static string PropertyName_LayerType = "layerType";
static GUIContent Label_LayerType = new GUIContent("Type", "Specify the type of the composition layer.");
SerializedProperty Property_LayerType;
static string PropertyName_CompositionDepth = "compositionDepth";
static GUIContent Label_CompositionDepth = new GUIContent("Composition Depth", "Specify the composition depth of the layer.");
SerializedProperty Property_CompositionDepth;
static string PropertyName_LayerShape = "layerShape";
static GUIContent Label_LayerShape = new GUIContent("Shape", "Specify the shape of the layer.");
SerializedProperty Property_LayerShape;
static string PropertyName_LayerVisibility = "layerVisibility";
static GUIContent Label_LayerVisibility = new GUIContent("Visibility", "Specify the visibility of the layer.");
SerializedProperty Property_LayerVisibility;
static string PropertyName_LockMode = "lockMode";
static GUIContent Label_LockMode = new GUIContent("Locked Parameter", "Cylinder Layer parameter to be locked when changing the radius.");
SerializedProperty Property_LockMode;
static string PropertyName_QuadWidth = "m_QuadWidth";
static GUIContent Label_QuadWidth = new GUIContent("Width", "Width of a Quad Layer");
SerializedProperty Property_QuadWidth;
static string PropertyName_QuadHeight = "m_QuadHeight";
static GUIContent Label_QuadHeight = new GUIContent("Height", "Height of a Quad Layer");
SerializedProperty Property_QuadHeight;
static string PropertyName_CylinderHeight = "m_CylinderHeight";
static GUIContent Label_CylinderHeight = new GUIContent("Height", "Height of Cylinder Layer");
SerializedProperty Property_CylinderHeight;
static string PropertyName_CylinderArcLength = "m_CylinderArcLength";
static GUIContent Label_CylinderArcLength = new GUIContent("Arc Length", "Arc Length of Cylinder Layer");
SerializedProperty Property_CylinderArcLength;
static string PropertyName_CylinderRadius = "m_CylinderRadius";
static GUIContent Label_CylinderRadius = new GUIContent("Radius", "Radius of Cylinder Layer");
SerializedProperty Property_CylinderRadius;
static string PropertyName_AngleOfArc = "m_CylinderAngleOfArc";
static GUIContent Label_AngleOfArc = new GUIContent("Arc Angle", "Central angle of arc of Cylinder Layer");
SerializedProperty Property_AngleOfArc;
static string PropertyName_IsDynamicLayer = "isDynamicLayer";
static GUIContent Label_IsDynamicLayer = new GUIContent("Dynamic Layer", "Specify whether Layer needs to be updated each frame or not.");
SerializedProperty Property_IsDynamicLayer;
static string PropertyName_ApplyColorScaleBias = "applyColorScaleBias";
static GUIContent Label_ApplyColorScaleBias = new GUIContent("Apply Color Scale Bias", "Color scale and bias are applied to a layer color during composition, after its conversion to premultiplied alpha representation. LayerColor = LayerColor * colorScale + colorBias");
SerializedProperty Property_ApplyColorScaleBias;
static string PropertyName_ColorScale = "colorScale";
static GUIContent Label_ColorScale = new GUIContent("Color Scale", "Will be used for modulatting the color sourced from the images.");
SerializedProperty Property_ColorScale;
static string PropertyName_ColorBias = "colorBias";
static GUIContent Label_ColorBias = new GUIContent("Color Bias", "Will be used for offseting the color sourced from the images.");
SerializedProperty Property_ColorBias;
static string PropertyName_IsProtectedSurface = "isProtectedSurface";
static GUIContent Label_IsProtectedSurface = new GUIContent("Protected Surface");
SerializedProperty Property_IsProtectedSurface;
static string PropertyName_RenderPriority = "renderPriority";
static GUIContent Label_RenderPriority = new GUIContent("Render Priority", "When Auto Fallback is enabled, layers with a higher render priority will be rendered as normal layers first.");
SerializedProperty Property_RenderPriority;
static string PropertyName_TrackingOrigin = "trackingOrigin";
static GUIContent Label_TrackingOrigin = new GUIContent("Tracking Origin", "Assign the tracking origin here to offset the pose of the Composition Layer.");
SerializedProperty Property_TrackingOrigin;
private bool showLayerParams = true, showColorScaleBiasParams = true;
#pragma warning disable
private bool showExternalSurfaceParams = false;
#pragma warning restore
public override void OnInspectorGUI()
{
if (Property_LayerType == null) Property_LayerType = serializedObject.FindProperty(PropertyName_LayerType);
if (Property_CompositionDepth == null) Property_CompositionDepth = serializedObject.FindProperty(PropertyName_CompositionDepth);
if (Property_LayerShape == null) Property_LayerShape = serializedObject.FindProperty(PropertyName_LayerShape);
if (Property_LayerVisibility == null) Property_LayerVisibility = serializedObject.FindProperty(PropertyName_LayerVisibility);
if (Property_LockMode == null) Property_LockMode = serializedObject.FindProperty(PropertyName_LockMode);
if (Property_QuadWidth == null) Property_QuadWidth = serializedObject.FindProperty(PropertyName_QuadWidth);
if (Property_QuadHeight == null) Property_QuadHeight = serializedObject.FindProperty(PropertyName_QuadHeight);
if (Property_CylinderHeight == null) Property_CylinderHeight = serializedObject.FindProperty(PropertyName_CylinderHeight);
if (Property_CylinderArcLength == null) Property_CylinderArcLength = serializedObject.FindProperty(PropertyName_CylinderArcLength);
if (Property_CylinderRadius == null) Property_CylinderRadius = serializedObject.FindProperty(PropertyName_CylinderRadius);
if (Property_AngleOfArc == null) Property_AngleOfArc = serializedObject.FindProperty(PropertyName_AngleOfArc);
if (Property_IsDynamicLayer == null) Property_IsDynamicLayer = serializedObject.FindProperty(PropertyName_IsDynamicLayer);
if (Property_ApplyColorScaleBias == null) Property_ApplyColorScaleBias = serializedObject.FindProperty(PropertyName_ApplyColorScaleBias);
if (Property_ColorScale == null) Property_ColorScale = serializedObject.FindProperty(PropertyName_ColorScale);
if (Property_ColorBias == null) Property_ColorBias = serializedObject.FindProperty(PropertyName_ColorBias);
if (Property_IsProtectedSurface == null) Property_IsProtectedSurface = serializedObject.FindProperty(PropertyName_IsProtectedSurface);
if (Property_RenderPriority == null) Property_RenderPriority = serializedObject.FindProperty(PropertyName_RenderPriority);
if (Property_TrackingOrigin == null) Property_TrackingOrigin = serializedObject.FindProperty(PropertyName_TrackingOrigin);
CompositionLayer targetCompositionLayer = target as CompositionLayer;
if (!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayer.featureId).enabled)
{
EditorGUILayout.HelpBox("The Composition Layer feature is not enabled in OpenXR Settings.\nEnable it to use the Composition Layer.", MessageType.Warning);
}
EditorGUILayout.PropertyField(Property_LayerType, new GUIContent(Label_LayerType));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_CompositionDepth, new GUIContent(Label_CompositionDepth));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_LayerShape, new GUIContent(Label_LayerShape));
serializedObject.ApplyModifiedProperties();
if (Property_LayerShape.intValue == (int)CompositionLayer.LayerShape.Cylinder)
{
if (!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayerCylinder.featureId).enabled)
{
EditorGUILayout.HelpBox("The Composition Layer Cylinder feature is not enabled in OpenXR Settings.\nEnable it to use Cylinder layers.", MessageType.Warning);
}
if (targetCompositionLayer.isPreviewingQuad)
{
targetCompositionLayer.isPreviewingQuad = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
Transform generatedQuadTransform = targetCompositionLayer.transform.Find(CompositionLayer.QuadUnderlayMeshName);
if (generatedQuadTransform != null)
{
DestroyImmediate(generatedQuadTransform.gameObject);
}
EditorGUI.indentLevel++;
showLayerParams = EditorGUILayout.Foldout(showLayerParams, "Cylinder Parameters");
if (showLayerParams)
{
float radiusLowerBound = Mathf.Max(0.001f, CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(targetCompositionLayer.cylinderArcLength, targetCompositionLayer.angleOfArcUpperLimit));
float radiusUpperBound = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(targetCompositionLayer.cylinderArcLength, targetCompositionLayer.angleOfArcLowerLimit);
EditorGUILayout.HelpBox("Changing the Arc Length will affect the upper and lower bounds of the radius.\nUpper Bound of Radius: " + radiusUpperBound + "\nLower Bound of Radius: " + radiusLowerBound, MessageType.Info);
EditorGUILayout.PropertyField(Property_CylinderRadius, new GUIContent(Label_CylinderRadius));
EditorGUILayout.PropertyField(Property_LockMode, new GUIContent(Label_LockMode));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.HelpBox("Arc Length and Arc Angle are correlated, adjusting one of them changes the other as well. The Radius will not be changed when adjusting these two values.", MessageType.Info);
if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength)
{
GUI.enabled = false;
EditorGUILayout.PropertyField(Property_CylinderArcLength, new GUIContent(Label_CylinderArcLength));
GUI.enabled = true;
EditorGUILayout.Slider(Property_AngleOfArc, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, new GUIContent(Label_AngleOfArc));
}
else if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle)
{
EditorGUILayout.PropertyField(Property_CylinderArcLength, new GUIContent(Label_CylinderArcLength));
GUI.enabled = false;
EditorGUILayout.Slider(Property_AngleOfArc, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, new GUIContent(Label_AngleOfArc));
GUI.enabled = true;
}
EditorGUILayout.PropertyField(Property_CylinderHeight, new GUIContent(Label_CylinderHeight));
}
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
CompositionLayer.CylinderLayerParamAdjustmentMode currentAdjustmentMode = targetCompositionLayer.CurrentAdjustmentMode();
switch (currentAdjustmentMode)
{
case CompositionLayer.CylinderLayerParamAdjustmentMode.ArcLength:
{
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
float cylinderArcLengthRef = targetCompositionLayer.CylinderArcLength;
if (!ArcLengthValidityCheck(ref cylinderArcLengthRef, targetCompositionLayer.CylinderRadius, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit))
{
targetCompositionLayer.CylinderArcLength = cylinderArcLengthRef;
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
}
serializedObject.ApplyModifiedProperties();
break;
}
case CompositionLayer.CylinderLayerParamAdjustmentMode.ArcAngle:
{
targetCompositionLayer.CylinderArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius);
serializedObject.ApplyModifiedProperties();
break;
}
case CompositionLayer.CylinderLayerParamAdjustmentMode.Radius:
default:
{
float cylinderRadiusRef = targetCompositionLayer.CylinderRadius;
RadiusValidityCheck(targetCompositionLayer.CylinderArcLength, ref cylinderRadiusRef, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit, targetCompositionLayer.lockMode);
targetCompositionLayer.CylinderRadius = cylinderRadiusRef;
if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength)
{
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
float cylinderArcLengthRef = targetCompositionLayer.CylinderArcLength;
if (!ArcLengthValidityCheck(ref cylinderArcLengthRef, targetCompositionLayer.CylinderRadius, targetCompositionLayer.angleOfArcLowerLimit, targetCompositionLayer.angleOfArcUpperLimit))
{
targetCompositionLayer.CylinderArcLength = cylinderArcLengthRef;
targetCompositionLayer.CylinderAngleOfArc = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(targetCompositionLayer.CylinderArcLength, targetCompositionLayer.CylinderRadius);
}
}
else if (targetCompositionLayer.lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle)
{
targetCompositionLayer.CylinderArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius);
}
serializedObject.ApplyModifiedProperties();
break;
}
}
EditorGUILayout.HelpBox("Current Layer Aspect Ratio (Arc Length : Height) = " + targetCompositionLayer.CylinderArcLength + " : " + targetCompositionLayer.CylinderHeight, MessageType.Info);
Vector3 CompositionLayerScale = targetCompositionLayer.gameObject.transform.localScale;
bool CylinderParamsChanged = targetCompositionLayer.LayerDimensionsChanged();
if (targetCompositionLayer.isPreviewingCylinder)
{
Transform generatedPreviewTransform = targetCompositionLayer.transform.Find(CompositionLayer.CylinderPreviewName);
if (generatedPreviewTransform != null)
{
targetCompositionLayer.generatedPreview = generatedPreviewTransform.gameObject;
if (CylinderParamsChanged)
{
//Generate vertices
Vector3[] cylinderVertices = CompositionLayer.MeshGenerationHelper.GenerateCylinderVertex(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius, targetCompositionLayer.CylinderHeight);;
MeshFilter cylinderMeshFilter = targetCompositionLayer.generatedPreview.GetComponent<MeshFilter>();
//Generate Mesh
cylinderMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateCylinderMesh(targetCompositionLayer.CylinderAngleOfArc, cylinderVertices);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
}
if (targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture != targetCompositionLayer.texture)
{
targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
if (GUILayout.Button("Hide Cylinder Preview"))
{
targetCompositionLayer.isPreviewingCylinder = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
}
else
{
targetCompositionLayer.isPreviewingCylinder = false;
}
}
else
{
if (GUILayout.Button("Show Cylinder Preview"))
{
targetCompositionLayer.isPreviewingCylinder = true;
Vector3[] cylinderVertices = CompositionLayer.MeshGenerationHelper.GenerateCylinderVertex(targetCompositionLayer.CylinderAngleOfArc, targetCompositionLayer.CylinderRadius, targetCompositionLayer.CylinderHeight);
//Add components to Game Object
targetCompositionLayer.generatedPreview = new GameObject();
targetCompositionLayer.generatedPreview.hideFlags = HideFlags.HideAndDontSave;
targetCompositionLayer.generatedPreview.name = CompositionLayer.CylinderPreviewName;
targetCompositionLayer.generatedPreview.transform.SetParent(targetCompositionLayer.gameObject.transform);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
MeshRenderer cylinderMeshRenderer = targetCompositionLayer.generatedPreview.AddComponent<MeshRenderer>();
MeshFilter cylinderMeshFilter = targetCompositionLayer.generatedPreview.AddComponent<MeshFilter>();
cylinderMeshRenderer.sharedMaterial = new Material(Shader.Find("Unlit/Transparent"));
if (targetCompositionLayer.texture != null)
{
cylinderMeshRenderer.sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
//Generate Mesh
cylinderMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateCylinderMesh(targetCompositionLayer.CylinderAngleOfArc, cylinderVertices);
}
}
EditorGUILayout.Space(10);
serializedObject.ApplyModifiedProperties();
}
else if (Property_LayerShape.intValue == (int)CompositionLayer.LayerShape.Quad)
{
if (targetCompositionLayer.isPreviewingCylinder)
{
targetCompositionLayer.isPreviewingCylinder = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
EditorGUI.indentLevel++;
showLayerParams = EditorGUILayout.Foldout(showLayerParams, "Quad Parameters");
if (showLayerParams)
{
EditorGUILayout.PropertyField(Property_QuadWidth, new GUIContent(Label_QuadWidth));
EditorGUILayout.PropertyField(Property_QuadHeight, new GUIContent(Label_QuadHeight));
}
EditorGUI.indentLevel--;
EditorGUILayout.HelpBox("Current Layer Aspect Ratio (Width : Height) = " + targetCompositionLayer.quadWidth + " : " + targetCompositionLayer.quadHeight, MessageType.Info);
Vector3 CompositionLayerScale = targetCompositionLayer.gameObject.transform.localScale;
bool QuadParamsChanged = targetCompositionLayer.LayerDimensionsChanged();
if (targetCompositionLayer.isPreviewingQuad)
{
Transform generatedPreviewTransform = targetCompositionLayer.transform.Find(CompositionLayer.QuadPreviewName);
if (generatedPreviewTransform != null)
{
targetCompositionLayer.generatedPreview = generatedPreviewTransform.gameObject;
if (QuadParamsChanged)
{
//Generate vertices
Vector3[] quadVertices = CompositionLayer.MeshGenerationHelper.GenerateQuadVertex(targetCompositionLayer.quadWidth, targetCompositionLayer.quadHeight);
MeshFilter quadMeshFilter = targetCompositionLayer.generatedPreview.GetComponent<MeshFilter>();
//Generate Mesh
quadMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateQuadMesh(quadVertices);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
}
if (targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture != targetCompositionLayer.texture)
{
targetCompositionLayer.generatedPreview.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
if (GUILayout.Button("Hide Quad Preview"))
{
targetCompositionLayer.isPreviewingQuad = false;
if (targetCompositionLayer.generatedPreview != null)
{
DestroyImmediate(targetCompositionLayer.generatedPreview);
}
}
}
else
{
targetCompositionLayer.isPreviewingQuad = false;
}
}
else
{
if (GUILayout.Button("Show Quad Preview"))
{
targetCompositionLayer.isPreviewingQuad = true;
//Generate vertices
Vector3[] quadVertices = CompositionLayer.MeshGenerationHelper.GenerateQuadVertex(targetCompositionLayer.quadWidth, targetCompositionLayer.quadHeight);
//Add components to Game Object
targetCompositionLayer.generatedPreview = new GameObject();
targetCompositionLayer.generatedPreview.hideFlags = HideFlags.HideAndDontSave;
targetCompositionLayer.generatedPreview.name = CompositionLayer.QuadPreviewName;
targetCompositionLayer.generatedPreview.transform.SetParent(targetCompositionLayer.gameObject.transform);
targetCompositionLayer.generatedPreview.transform.localPosition = Vector3.zero;
targetCompositionLayer.generatedPreview.transform.localRotation = Quaternion.identity;
targetCompositionLayer.generatedPreview.transform.localScale = targetCompositionLayer.GetNormalizedLocalScale(targetCompositionLayer.transform, Vector3.one);
MeshRenderer quadMeshRenderer = targetCompositionLayer.generatedPreview.AddComponent<MeshRenderer>();
MeshFilter quadMeshFilter = targetCompositionLayer.generatedPreview.AddComponent<MeshFilter>();
quadMeshRenderer.sharedMaterial = new Material(Shader.Find("Unlit/Transparent"));
if (targetCompositionLayer.texture != null)
{
quadMeshRenderer.sharedMaterial.mainTexture = targetCompositionLayer.texture;
}
//Generate Mesh
quadMeshFilter.mesh = CompositionLayer.MeshGenerationHelper.GenerateQuadMesh(quadVertices);
}
}
}
//Rect UI For textures
Rect labelRect = EditorGUILayout.GetControlRect();
EditorGUI.LabelField(new Rect(labelRect.x, labelRect.y, labelRect.width / 2, labelRect.height), new GUIContent("Texture", "Texture to be rendered on the layer"));
Rect textureRect = EditorGUILayout.GetControlRect(GUILayout.Height(64));
targetCompositionLayer.texture = (Texture)EditorGUI.ObjectField(new Rect(textureRect.x, textureRect.y, 64, textureRect.height), targetCompositionLayer.texture, typeof(Texture), true);
EditorGUILayout.PropertyField(Property_LayerVisibility, new GUIContent(Label_LayerVisibility));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_IsDynamicLayer, Label_IsDynamicLayer);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_ApplyColorScaleBias, Label_ApplyColorScaleBias);
serializedObject.ApplyModifiedProperties();
if (targetCompositionLayer.applyColorScaleBias)
{
if(!FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayerColorScaleBias.featureId).enabled)
{
EditorGUILayout.HelpBox("The Color Scale Bias feature is not enabled in OpenXR Settings.", MessageType.Warning);
}
EditorGUI.indentLevel++;
showColorScaleBiasParams = EditorGUILayout.Foldout(showColorScaleBiasParams, "Color Scale Bias Parameters");
if (showColorScaleBiasParams)
{
EditorGUILayout.PropertyField(Property_ColorScale, Label_ColorScale);
EditorGUILayout.PropertyField(Property_ColorBias, Label_ColorBias);
serializedObject.ApplyModifiedProperties();
}
EditorGUI.indentLevel--;
}
ViveCompositionLayer compositionLayerFeature = (ViveCompositionLayer)FeatureHelpers.GetFeatureWithIdForBuildTarget(BuildTargetGroup.Android, ViveCompositionLayer.featureId);
if (compositionLayerFeature != null && compositionLayerFeature.enableAutoFallback)
{
EditorGUILayout.PropertyField(Property_RenderPriority, new GUIContent(Label_RenderPriority));
serializedObject.ApplyModifiedProperties();
}
EditorGUILayout.PropertyField(Property_TrackingOrigin, Label_TrackingOrigin);
serializedObject.ApplyModifiedProperties();
}
public static bool RadiusValidityCheck(float inArcLength, ref float inRadius, float thetaLowerLimit, float thetaUpperLimit, CompositionLayer.CylinderLayerParamLockMode lockMode)
{
bool isValid = true;
if (inRadius <= 0)
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
isValid = false;
return isValid;
}
float degThetaResult = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(inArcLength, inRadius);
if (degThetaResult < thetaLowerLimit)
{
if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle) //Angle locked, increase arc length
{
ArcLengthValidityCheck(ref inArcLength, inRadius, thetaLowerLimit, thetaUpperLimit);
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaLowerLimit);
}
else if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength) //ArcLength Locked, keep angle at min
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaLowerLimit);
}
isValid = false;
}
else if (degThetaResult > thetaUpperLimit)
{
if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcAngle) //Angle locked, decrease arc length
{
ArcLengthValidityCheck(ref inArcLength, inRadius, thetaLowerLimit, thetaUpperLimit);
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
}
else if (lockMode == CompositionLayer.CylinderLayerParamLockMode.ArcLength) //ArcLength Locked, keep angle at max
{
inRadius = CompositionLayer.CylinderParameterHelper.ArcLengthAndDegAngleOfArcToRadius(inArcLength, thetaUpperLimit);
}
isValid = false;
}
return isValid;
}
public static bool ArcLengthValidityCheck(ref float inArcLength, float inRadius, float thetaLowerLimit, float thetaUpperLimit)
{
bool isValid = true;
if (inArcLength <= 0)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaLowerLimit, inRadius);
isValid = false;
return isValid;
}
float degThetaResult = CompositionLayer.CylinderParameterHelper.RadiusAndArcLengthToDegAngleOfArc(inArcLength, inRadius);
if (degThetaResult < thetaLowerLimit)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaLowerLimit, inRadius);
isValid = false;
}
else if (degThetaResult > thetaUpperLimit)
{
inArcLength = CompositionLayer.CylinderParameterHelper.RadiusAndDegAngleOfArcToArcLength(thetaUpperLimit, inRadius);
isValid = false;
}
return isValid;
}
}
#endregion
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a99cc2a2471f1e7499276e561bbb8d1e
guid: ec04348c6d3a8ce43ada545a76766344
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,308 @@
// "VIVE SDK
// © 2020 HTC Corporation. All Rights Reserved.
//
// Unless otherwise required by copyright law and practice,
// upon the execution of HTC SDK license agreement,
// HTC grants you access to and use of the VIVE SDK(s).
// You shall fully comply with all of HTCs SDK license agreement terms and
// conditions signed by you and all SDK and API requirements,
// specifications, and documentation provided by HTC to You."
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace VIVE.OpenXR.CompositionLayer.Editor
{
using UnityEditor;
using UnityEngine.UI;
[CustomEditor(typeof(CompositionLayerUICanvas))]
public class CompositionLayerUICanvasEditor : Editor
{
static string PropertyName_MaxRenderTextureSize = "maxRenderTextureSize";
static GUIContent Label_MaxRenderTextureSize = new GUIContent("Max Render Texture Size", "Maximum render texture dimension. e.g. If maxRenderTextureSize is 1024, the render texture dimensions of a canvas with an Aspect Ratio of 2:1 will be 1024 x 512.");
SerializedProperty Property_MaxRenderTextureSize;
static string PropertyName_LayerType = "layerType";
static GUIContent Label_LayerType = new GUIContent("Layer Type", "Overlays render on top of all in-game objects.\nUnderlays can be occluded by in-game objects but may introduce alpha blending issues with transparent objects.");
SerializedProperty Property_LayerType;
static string PropertyName_LayerVisibility = "layerVisibility";
static GUIContent Label_LayerVisibility = new GUIContent("Visibility", "Specify the visibility of the layer.");
SerializedProperty Property_LayerVisibility;
static string PropertyName_CameraBGColor = "cameraBGColor";
static GUIContent Label_CameraBGColor = new GUIContent("Camera Background Color", "Background color of the camera for rendering the Canvas to the render texture target.\nChanging this option will affect the tint of the final image of the Canvas if no background gameobject is assigned.");
SerializedProperty Property_CameraBGColor;
static string PropertyName_BackgroundGO = "backgroundGO";
static GUIContent Label_BackgroundGO = new GUIContent("Background GameObject", "GameObject that contains a UI Component and will be used as the background of the Canvas.\nWhen succesfully assigned, the area which the background UI component covers will no longer be affected by the background color of the camera.");
SerializedProperty Property_BackgroundGO;
static string PropertyName_EnableAlphaBlendingCorrection = "enableAlphaBlendingCorrection";
static GUIContent Label_EnableAlphaBlendingCorrection = new GUIContent("Enable Alpha Blending Correction", "Enable this option if transparent UI elements are rendering darker than expected in an overall sense.\nNote that enabling this option will consume more resources.");
SerializedProperty Property_EnableAlphaBlendingCorrection;
static string PropertyName_CompositionDepth = "compositionDepth";
static GUIContent Label_CompositionDepth = new GUIContent("Composition Depth", "Specify Layer Composition Depth.");
SerializedProperty Property_CompositionDepth;
static string PropertyName_RenderPriority = "renderPriority";
static GUIContent Label_RenderPriority = new GUIContent("Render Priority", "When Auto Fallback is enabled, layers with a higher render priority will be rendered as normal layers first.");
SerializedProperty Property_RenderPriority;
static string PropertyName_TrackingOrigin = "trackingOrigin";
static GUIContent Label_TrackingOrigin = new GUIContent("Tracking Origin", "Assign the tracking origin here to offset the pose of the Composition Layer.");
SerializedProperty Property_TrackingOrigin;
bool isCurrentBackgroundGOValid = true, isMaterialReplaced = true, backgroundUINotFoundError = false, backgroundObjectNotChildError = false;
List<GameObject> validbackgroundGO;
private const string layerNameString = "CompositionLayerUICanvas";
public override void OnInspectorGUI()
{
//Check if current selected layer is rendered by main camera
if (Property_MaxRenderTextureSize == null) Property_MaxRenderTextureSize = serializedObject.FindProperty(PropertyName_MaxRenderTextureSize);
if (Property_LayerType == null) Property_LayerType = serializedObject.FindProperty(PropertyName_LayerType);
if (Property_LayerVisibility == null) Property_LayerVisibility = serializedObject.FindProperty(PropertyName_LayerVisibility);
if (Property_CameraBGColor == null) Property_CameraBGColor = serializedObject.FindProperty(PropertyName_CameraBGColor);
if (Property_BackgroundGO == null) Property_BackgroundGO = serializedObject.FindProperty(PropertyName_BackgroundGO);
if (Property_EnableAlphaBlendingCorrection == null) Property_EnableAlphaBlendingCorrection = serializedObject.FindProperty(PropertyName_EnableAlphaBlendingCorrection);
if (Property_CompositionDepth == null) Property_CompositionDepth = serializedObject.FindProperty(PropertyName_CompositionDepth);
if (Property_RenderPriority == null) Property_RenderPriority = serializedObject.FindProperty(PropertyName_RenderPriority);
if (Property_TrackingOrigin == null) Property_TrackingOrigin = serializedObject.FindProperty(PropertyName_TrackingOrigin);
CompositionLayerUICanvas targetLayerCanvasUI = target as CompositionLayerUICanvas;
Graphic[] graphicComponents = targetLayerCanvasUI.GetComponentsInChildren<Graphic>();
EditorGUILayout.HelpBox("CompositionLayerUICanvas will automatically generate the components necessary for rendering UI Canvas(es) with CompositionLayer(s).", MessageType.Info);
EditorGUILayout.PropertyField(Property_MaxRenderTextureSize, Label_MaxRenderTextureSize);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_LayerType, Label_LayerType);
serializedObject.ApplyModifiedProperties();
if (targetLayerCanvasUI.layerType == CompositionLayer.LayerType.Underlay)
{
EditorGUILayout.HelpBox("When using Underlay, overlapping non-opaque canvas elements (i.e. elements with alpha value < 1) might look different during runtime due to inherent alpha blending limitations.\n", MessageType.Warning);
EditorGUILayout.PropertyField(Property_EnableAlphaBlendingCorrection, Label_EnableAlphaBlendingCorrection);
serializedObject.ApplyModifiedProperties();
}
else
{
targetLayerCanvasUI.enableAlphaBlendingCorrection = false;
}
EditorGUILayout.PropertyField(Property_LayerVisibility, new GUIContent(Label_LayerVisibility));
serializedObject.ApplyModifiedProperties();
if (isCurrentBackgroundGOValid) //Cache valid result
{
validbackgroundGO = new List<GameObject>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
validbackgroundGO.Add(backgroundGO);
}
}
List<GameObject> prevBackgroundGO = new List<GameObject>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
prevBackgroundGO.Add(backgroundGO);
}
EditorGUILayout.PropertyField(Property_BackgroundGO, Label_BackgroundGO);
serializedObject.ApplyModifiedProperties();
bool needMaterialReplacement = false;
if (targetLayerCanvasUI.backgroundGO != null)
{
List<Graphic> backgroundGraphics = new List<Graphic>();
foreach (GameObject backgroundGO in targetLayerCanvasUI.backgroundGO)
{
if (backgroundGO == null) continue;
backgroundGraphics.Add(backgroundGO.GetComponent<Graphic>());
}
bool backgroundGraphicIsInChild = false;
if (backgroundGraphics.Count > 0)
{
foreach (Graphic backgroundGraphic in backgroundGraphics) //Loop through graphic components of selected background objects
{
if (backgroundGraphic != null)
{
backgroundUINotFoundError = false;
foreach (Graphic graphicComponent in graphicComponents) //Loop through graphic components under current canvas
{
if (graphicComponent == backgroundGraphic)
{
backgroundGraphicIsInChild = true;
backgroundObjectNotChildError = false;
break;
}
backgroundGraphicIsInChild = false;
}
if (!backgroundGraphicIsInChild) //Triggers when one of the selected objects is invalid
{
backgroundObjectNotChildError = true;
break;
}
}
else
{
backgroundUINotFoundError = true;
break;
}
}
if (!backgroundUINotFoundError && !backgroundObjectNotChildError)
{
isCurrentBackgroundGOValid = true;
foreach (GameObject backgroundGOCurr in targetLayerCanvasUI.backgroundGO)
{
if (backgroundGOCurr == null) continue;
if (!prevBackgroundGO.Contains(backgroundGOCurr)) //Needs material replacement
{
needMaterialReplacement = true;
isMaterialReplaced = false;
break;
}
}
EditorGUILayout.HelpBox("The blending mode of the background UI shader will be changed in order to ignore the background color of the camera.", MessageType.Info);
}
else
{
isCurrentBackgroundGOValid = false;
if (backgroundUINotFoundError)
{
EditorGUILayout.HelpBox("The background object you are trying to assign does not contain a UI Component.", MessageType.Error);
}
if (backgroundObjectNotChildError)
{
EditorGUILayout.HelpBox("The background object you are trying to assign is not under the current Canvas.", MessageType.Error);
}
if (GUILayout.Button("Revert Background GameObjects"))
{
targetLayerCanvasUI.backgroundGO = validbackgroundGO;
}
}
}
}
EditorGUILayout.PropertyField(Property_CameraBGColor, Label_CameraBGColor);
serializedObject.ApplyModifiedProperties();
//Check the material config of the UI elements
foreach (Graphic graphicComponent in graphicComponents)
{
if (graphicComponent.material == null || graphicComponent.material == graphicComponent.defaultMaterial)
{
needMaterialReplacement = true;
isMaterialReplaced = false;
break;
}
}
if (needMaterialReplacement || !isMaterialReplaced)
{
EditorGUILayout.HelpBox("The current material configurations of the UI elements will lead to incorrect alpha blending.\n" +
"Replace the materials to yield better visual results.", MessageType.Error);
if (GUILayout.Button("Replace UI Materials"))
{
targetLayerCanvasUI.ReplaceUIMaterials();
isMaterialReplaced = true;
}
}
//Check if current selected layer is rendered by main camera
if (Camera.main != null)
{
if ((Camera.main.cullingMask & (1 << targetLayerCanvasUI.gameObject.layer)) != 0)
{
EditorGUILayout.HelpBox("Currently selected layer: " + LayerMask.LayerToName(targetLayerCanvasUI.gameObject.layer) + "\nThis layer is not culled by the Main Camera.\nSelect a layer that will not be rendered by the Main Camera and apply it to all child objects.", MessageType.Error);
//TODO: Add Auto Layer button
if (GUILayout.Button("Auto Select Layer"))
{
// Open tag manager
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
// Layers Property
SerializedProperty layersProp = tagManager.FindProperty("layers");
//Check if the layer CompositionLayerUICanvas exists
bool layerExists = false, firstEmptyLayerFound = false;
int emptyLayerIndex = 0;
for (int i = 0; i < layersProp.arraySize; i++)
{
if (layersProp.GetArrayElementAtIndex(i).stringValue == layerNameString)
{
layerExists = true;
ApplyLayerToGameObjectRecursive(targetLayerCanvasUI.gameObject, i);
break;
}
else if (layersProp.GetArrayElementAtIndex(i).stringValue == "")
{
if (!firstEmptyLayerFound) //Remember the index of the first empty layer
{
firstEmptyLayerFound = true;
emptyLayerIndex = i;
}
}
}
if (!layerExists) //Create layer and apply it
{
layersProp.GetArrayElementAtIndex(emptyLayerIndex).stringValue = layerNameString;
ApplyLayerToGameObjectRecursive(targetLayerCanvasUI.gameObject, emptyLayerIndex);
tagManager.ApplyModifiedProperties();
}
}
}
}
else
{
EditorGUILayout.HelpBox("Main Camera not found, and hence cannot confirm the status of its Culling Mask.\nMake sure that the Main Camera does not draw the " + LayerMask.LayerToName(targetLayerCanvasUI.gameObject.layer) + " layer." , MessageType.Warning);
}
EditorGUILayout.PropertyField(Property_CompositionDepth, Label_CompositionDepth);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_RenderPriority, Label_RenderPriority);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_TrackingOrigin, Label_TrackingOrigin);
serializedObject.ApplyModifiedProperties();
}
private void ApplyLayerToGameObjectRecursive(GameObject targetGO, int layerID)
{
if (targetGO.transform.childCount > 0)
{
for (int i=0; i<targetGO.transform.childCount; i++)
{
ApplyLayerToGameObjectRecursive(targetGO.transform.GetChild(i).gameObject, layerID);
}
}
targetGO.layer = layerID;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 03f67eb290fa9f3468b94c84f9f50e84
guid: 222aadbc313466a41bafc2f46013fe3d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

@@ -1,34 +0,0 @@
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;
namespace HTC.Vive.OpenXR.Editor
{
[OpenXRFeatureSet(
FeatureSetId = featureSetId,
FeatureIds = new string[]
{
"com.htc.openxr.sceneunderstanding.feature",
"com.htc.openxr.facialtracking.feature",
"com.htc.openxr.feature.input.htcvivecosmos",
"com.company.openxr.handtracking.feature",
"com.htc.openxr.feature.input.htcvivefocus3",
"com.htc.openxr.feature.input.htcvivehandinteraction"
},
DefaultFeatureIds = new string[]
{
"com.htc.openxr.sceneunderstanding.feature",
"com.htc.openxr.facialtracking.feature",
"com.htc.openxr.feature.input.htcvivecosmos",
"com.company.openxr.handtracking.feature",
"com.htc.openxr.feature.input.htcvivefocus3",
"com.htc.openxr.feature.input.htcvivehandinteraction"
},
UiName = "VIVE OpenXR",
Description = "Enable the full suite of features for Vive OpenXR.",
SupportedBuildTargets = new BuildTargetGroup[] { BuildTargetGroup.Standalone }
)]
sealed class VIVEFeatureSet
{
internal const string featureSetId = "com.HTC.openxr.featureset.vive";
}
}

View File

@@ -0,0 +1,21 @@
{
"name": "VIVE.OpenXR.Editor",
"rootNamespace": "",
"references": [
"VIVE.OpenXR",
"Unity.XR.OpenXR",
"Unity.XR.OpenXR.Editor",
"Unity.XR.Management.Editor"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c34271c4bb951904aa11cacc978a4396
guid: d6b33c0ff458eb344807c1608836e334
AssemblyDefinitionImporter:
externalObjects: {}
userData:

View File

@@ -0,0 +1,30 @@
// Copyright HTC Corporation All Rights Reserved.
#if UNITY_EDITOR
using UnityEditor;
namespace VIVE.OpenXR.Editor
{
[CustomEditor(typeof(VIVEFocus3Feature))]
internal class VIVEFocus3FeatureEditor : UnityEditor.Editor
{
//private SerializedProperty enableHandTracking;
//private SerializedProperty enableTracker;
void OnEnable()
{
//enableHandTracking = serializedObject.FindProperty("enableHandTracking");
//enableTracker = serializedObject.FindProperty("enableTracker");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
//EditorGUILayout.PropertyField(enableHandTracking);
//EditorGUILayout.PropertyField(enableTracker);
serializedObject.ApplyModifiedProperties();
}
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9d6ba0632411b7742b59d20955e2ea57
guid: b048c9b388bf8d34e9814b272da7ddb5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,30 @@
// Copyright HTC Corporation All Rights Reserved.
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;
namespace VIVE.OpenXR
{
[OpenXRFeatureSet(
FeatureIds = new string[] {
VIVEFocus3Feature.featureId,
VIVEFocus3Profile.featureId,
Hand.ViveHandTracking.featureId,
"vive.vive.openxr.feature.compositionlayer",
"vive.vive.openxr.feature.compositionlayer.cylinder",
"vive.vive.openxr.feature.compositionlayer.colorscalebias",
Tracker.ViveWristTracker.featureId,
Hand.ViveHandInteraction.featureId,
"vive.vive.openxr.feature.foveation",
FacialTracking.ViveFacialTracking.featureId,
},
UiName = "VIVE XR Support",
Description = "Necessary to deploy an VIVE XR compatible app.",
FeatureSetId = "com.htc.vive.openxr.featureset.vivexr",
DefaultFeatureIds = new string[] { VIVEFocus3Feature.featureId, VIVEFocus3Profile.featureId, },
SupportedBuildTargets = new BuildTargetGroup[] { BuildTargetGroup.Android }
)]
sealed class VIVEFocus3FeatureSet { }
}
#endif

View File

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

View File

@@ -0,0 +1,26 @@
#if UNITY_EDITOR
using UnityEditor;
namespace VIVE.OpenXR.CompositionLayer
{
[CustomEditor(typeof(ViveCompositionLayer))]
internal class ViveCompositionLayerEditor : UnityEditor.Editor
{
private SerializedProperty enableAutoFallback;
void OnEnable()
{
enableAutoFallback = serializedObject.FindProperty("enableAutoFallback");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(enableAutoFallback);
serializedObject.ApplyModifiedProperties();
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,131 @@
// Copyright HTC Corporation All Rights Reserved.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.XR.Management.Metadata;
namespace VIVE.OpenXR.Editor
{
[InitializeOnLoad]
public static class CheckIfVIVEEnabled
{
const string LOG_TAG = "VIVE.OpenXR.Editor.CheckIfVIVEEnabled";
static void DEBUG(string msg) { Debug.Log(LOG_TAG + " " + msg); }
const string VERSION_DEFINE_OPENXR = "USE_VIVE_OPENXR_1_0_0";
internal struct ScriptingDefinedSettings
{
public string[] scriptingDefinedSymbols;
public BuildTargetGroup[] targetGroups;
public ScriptingDefinedSettings(string[] symbols, BuildTargetGroup[] groups)
{
scriptingDefinedSymbols = symbols;
targetGroups = groups;
}
}
static readonly ScriptingDefinedSettings m_ScriptDefineSettingOpenXRAndroid = new ScriptingDefinedSettings(
new string[] { VERSION_DEFINE_OPENXR, },
new BuildTargetGroup[] { BuildTargetGroup.Android, }
);
const string XR_LOADER_OPENXR_NAME = "UnityEngine.XR.OpenXR.OpenXRLoader";
internal static bool ViveOpenXRAndroidAssigned { get { return XRPackageMetadataStore.IsLoaderAssigned(XR_LOADER_OPENXR_NAME, BuildTargetGroup.Android); } }
static void AddScriptingDefineSymbols(ScriptingDefinedSettings setting)
{
for (int group_index = 0; group_index < setting.targetGroups.Length; group_index++)
{
var group = setting.targetGroups[group_index];
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
List<string> allDefines = definesString.Split(';').ToList();
for (int symbol_index = 0; symbol_index < setting.scriptingDefinedSymbols.Length; symbol_index++)
{
if (!allDefines.Contains(setting.scriptingDefinedSymbols[symbol_index]))
{
DEBUG("AddDefineSymbols() " + setting.scriptingDefinedSymbols[symbol_index] + " to group " + group);
allDefines.Add(setting.scriptingDefinedSymbols[symbol_index]);
}
else
{
DEBUG("AddDefineSymbols() " + setting.scriptingDefinedSymbols[symbol_index] + " already existed.");
}
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(
group,
string.Join(";", allDefines.ToArray())
);
}
}
static void RemoveScriptingDefineSymbols(ScriptingDefinedSettings setting)
{
for (int group_index = 0; group_index < setting.targetGroups.Length; group_index++)
{
var group = setting.targetGroups[group_index];
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
List<string> allDefines = definesString.Split(';').ToList();
for (int symbol_index = 0; symbol_index < setting.scriptingDefinedSymbols.Length; symbol_index++)
{
if (allDefines.Contains(setting.scriptingDefinedSymbols[symbol_index]))
{
DEBUG("RemoveDefineSymbols() " + setting.scriptingDefinedSymbols[symbol_index] + " from group " + group);
allDefines.Remove(setting.scriptingDefinedSymbols[symbol_index]);
}
else
{
DEBUG("RemoveDefineSymbols() " + setting.scriptingDefinedSymbols[symbol_index] + " already existed.");
}
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(
group,
string.Join(";", allDefines.ToArray())
);
}
}
static bool HasScriptingDefineSymbols(ScriptingDefinedSettings setting)
{
for (int group_index = 0; group_index < setting.targetGroups.Length; group_index++)
{
var group = setting.targetGroups[group_index];
string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
List<string> allDefines = definesString.Split(';').ToList();
for (int symbol_index = 0; symbol_index < setting.scriptingDefinedSymbols.Length; symbol_index++)
{
if (!allDefines.Contains(setting.scriptingDefinedSymbols[symbol_index]))
{
return false;
}
}
}
return true;
}
static void OnUpdate()
{
// Adds the script symbol if Vive OpenXR Plugin - Android is imported and assigned in XR Plugin-in Management.
if (ViveOpenXRAndroidAssigned)
{
if (!HasScriptingDefineSymbols(m_ScriptDefineSettingOpenXRAndroid))
{
DEBUG("OnUpdate() Adds m_ScriptDefineSettingOpenXRAndroid.");
AddScriptingDefineSymbols(m_ScriptDefineSettingOpenXRAndroid);
}
}
// Removes the script symbol if Vive OpenXR Plugin - Android is uninstalled.
else
{
if (HasScriptingDefineSymbols(m_ScriptDefineSettingOpenXRAndroid))
{
DEBUG("OnUpdate() Removes m_ScriptDefineSettingOpenXRAndroid.");
RemoveScriptingDefineSymbols(m_ScriptDefineSettingOpenXRAndroid);
}
}
}
static CheckIfVIVEEnabled()
{
EditorApplication.update += OnUpdate;
}
}
}
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
================================================================================
Copyright 2017-2021, HTC Corporation. All rights reserved.
================================================================================
Unless otherwise provided herein or in the folder you download or use, the information in this Work is the exclusive property of HTC.
Please note that this Work includes VIVE SDK native binary which is subject to a sperate license agreement described below. You can find more detailed information about VIVE SDK and its available plugin software packages at VIVE developer resource page (https://developer.vive.com/resources/knowledgebase/wave-sdk/).
*VIVE SDK native binary:
Your use of VIVE SDK native binary will be subject to SDK License Agreement between you and HTC. You can find the text of license agreement at https://developer.vive.com/resources/knowledgebase/sdk-license-agreement-english-version/. Please read it carefully before using this Work.
*VIVE SDK Plugin Package:
Your use of plugin software package will be subject to the license terms contemplated herein. You can use, modify, share and/or reproduce the VIVE SDK Plugin Package in accordance with the Agreement herein.
If you do not agree to the terms of the Agreement, please do not use this Work.
The VIVE SDK native binary contains some third party software which separate license terms may apply. Please refer to the Accompanying License in a separate file named “VIVE SDK Native Binary Accompanying OSS License”.
================================================================================
License Terms for VIVE SDK Plugin Package
The works ("Work") herein refer to the software developed or owned by
HTC Corporation ("HTC") under the terms of the license. Unless otherwise
provided herein or in the folder you download or use, the information in
this Work is the exclusive property of HTC. HTC grants the
legal user the right to use the Work within the scope of the legitimate
development of software. No further right is granted under this license,
including but not limited to, distribution, reproduction and
modification. Any other usage of the Works shall be subject to the
written consent of HTC.
The use of the Work is permitted provided that the following conditions
are met:
* The Work is used in a source code form must retain the above
copyright notice, this list of conditions and the following
disclaimer.
* The Work is used in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distributions.
* Neither HTC nor the names of its contributors may be used to
endorse or promote products derived from this software without
specific prior written permission.
THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER
DEALINGS IN THE WORK.

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8d77374400df33e4396eb7e610d731d7
guid: ecdb711833cec9e49b0c978f3f9aada1
DefaultImporter:
externalObjects: {}
userData:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,43 +0,0 @@
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using System.Linq;
using System.IO;
using VIVE.FacialTracking;
namespace UnityEditor.XR.OpenXR.Samples.FacialTracking
{
[InitializeOnLoad]
public class FacialTrackingFeatureInstaller : Editor
{
#if !UNITY_SAMPLE_DEV
private const string k_ScriptPath = "FacialTracking Example/Editor/FacialTrackingFeatureInstaller.cs";
static FacialTrackingFeatureInstaller()
{
FeatureHelpers.RefreshFeatures(BuildTargetGroup.Standalone);
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
if (feature != null)
{
if (feature.enabled != true)
{
feature.enabled = true;
}
}
Debug.Log(AssetDatabase.FindAssets(Path.GetFileNameWithoutExtension(k_ScriptPath)).Select(AssetDatabase.GUIDToAssetPath));
var source = AssetDatabase.FindAssets(Path.GetFileNameWithoutExtension(k_ScriptPath))
.Select(AssetDatabase.GUIDToAssetPath)
.FirstOrDefault(r => r.Contains(k_ScriptPath));
if (string.IsNullOrEmpty(source))
{
Debug.LogError("File Not Exist");
return;
}
source = Path.GetDirectoryName(source);
Debug.Log(source);
AssetDatabase.DeleteAsset(Path.Combine(Path.GetDirectoryName(source), "Editor"));
}
#endif
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,465 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3051409913850635161
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3051409913850609593}
- component: {fileID: 3051409913849839515}
- component: {fileID: 3051409913848708443}
m_Layer: 0
m_Name: Eye_Left
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3051409913850609593
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635161}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0.034480397, y: 0.008242355, z: 0.078922845}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 3051409913850609595}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &3051409913849839515
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635161}
m_Mesh: {fileID: 4300002, guid: cc2bd8780f283784899dcb72f2f7702f, type: 3}
--- !u!23 &3051409913848708443
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635161}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 64185bf5c669e274ca89bb76c87d1429, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1 &3051409913850635163
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3051409913850609595}
- component: {fileID: 3051409913860149339}
- component: {fileID: 3051409913850733895}
- component: {fileID: 3051409913850733890}
m_Layer: 0
m_Name: Avatar_Shieh_V2
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3051409913850609595
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635163}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: -0.04, z: -0.158}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 3051409913850609593}
- {fileID: 3051409913850609599}
- {fileID: 3051409913850609597}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!95 &3051409913860149339
Animator:
serializedVersion: 3
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635163}
m_Enabled: 1
m_Avatar: {fileID: 9000000, guid: cc2bd8780f283784899dcb72f2f7702f, type: 3}
m_Controller: {fileID: 0}
m_CullingMode: 1
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorControllerStateOnDisable: 0
--- !u!114 &3051409913850733895
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635163}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2872c722b18f6d043ad0dbae08561d64, type: 3}
m_Name:
m_EditorClassIdentifier:
EyesModels:
- {fileID: 3051409913850609593}
- {fileID: 3051409913850609599}
EyeShapeTables:
- skinnedMeshRenderer: {fileID: 3051409913864302235}
eyeShapes: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
EyebrowAnimationCurveUpper:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
EyebrowAnimationCurveLower:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
EyebrowAnimationCurveHorizontal:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
NeededToGetData: 1
--- !u!114 &3051409913850733890
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635163}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 42350b51669fc604cb2cad73c39f116c, type: 3}
m_Name:
m_EditorClassIdentifier:
LipShapeTables:
- skinnedMeshRenderer: {fileID: 3051409913864302235}
lipShapes: 010000000000000002000000030000000400000006000000050000000800000007000000090000000a0000000b0000000d0000000c0000000f0000000e00000011000000100000001200000014000000130000001600000015000000170000001800000019000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1a000000200000001b0000001c0000001d0000001e0000001f00000022000000210000002400000023000000
NeededToGetData: 1
--- !u!1 &3051409913850635165
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3051409913850609597}
- component: {fileID: 3051409913864302235}
m_Layer: 0
m_Name: Head
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3051409913850609597
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635165}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -0, y: -0.05097887, z: 0.004202667}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 3051409913850609595}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!137 &3051409913864302235
SkinnedMeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635165}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 3
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 64185bf5c669e274ca89bb76c87d1429, type: 2}
- {fileID: 2100000, guid: ed4b25628f9822042ae28821748b430f, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
serializedVersion: 2
m_Quality: 0
m_UpdateWhenOffscreen: 1
m_SkinnedMotionVectors: 1
m_Mesh: {fileID: 4300000, guid: cc2bd8780f283784899dcb72f2f7702f, type: 3}
m_Bones: []
m_BlendShapeWeights:
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
m_RootBone: {fileID: 0}
m_AABB:
m_Center: {x: 0, y: 0, z: 0.0039771833}
m_Extent: {x: 0.0988433, y: 0.18122566, z: 0.12538658}
m_DirtyAABB: 0
--- !u!1 &3051409913850635167
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3051409913850609599}
- component: {fileID: 3051409913849839513}
- component: {fileID: 3051409913848708441}
m_Layer: 0
m_Name: Eye_Right
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3051409913850609599
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635167}
m_LocalRotation: {x: 0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.034480397, y: 0.008242355, z: 0.078922845}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 3051409913850609595}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &3051409913849839513
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635167}
m_Mesh: {fileID: 4300004, guid: cc2bd8780f283784899dcb72f2f7702f, type: 3}
--- !u!23 &3051409913848708441
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3051409913850635167}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 64185bf5c669e274ca89bb76c87d1429, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}

View File

@@ -1,19 +0,0 @@
# VIVE OpenXR Facial Tracking Unity Feature
To help software developers create an application with actual facial expressions on 3D avatars with the OpenXR facial tracing extension [XR_HTC_facial_tracking](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_facial_tracking).
## Load sample code
**Window** > **Package Manager** > **VIVE OpenXR Plugin - Windows** > **Samples** > Click to import **FacialTracking Example**
## Play the sample scene
1. **Edit** > **Project Settings** > **XR Plug-in Management** > Select **OpenXR** , click Exclamation mark next to it then choose **Fix All**.
2. **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR** > Add Interaction profiles for your device.
3. **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR** > Select **Facial Tracking** under **VIVE OpenXR** Feature Groups.
4. In the Unity Project window, select the sample scene file in **Assets** > **Samples** > **VIVE OpenXR Plugin - Windows** > **1.0.13** > **FacialTracking Example** > **Scenes** > **FaceSample.unity** then click Play.
## How to use VIVE OpenXR Facial Tracking Unity Feature
1. Import VIVE OpenXR Plugin - Windows
2. Add your avatar object to the Unity scene.
- Attach "AvatarEyeSample.cs" and "AvatarLipSample.cs" to your avatar object or Drag "Avatar_Shieh_V2" prefab into scene hierarchy.
- Refer to functions **StartFrameWork** and **StopFrameWork** in **FacialManager.cs** for creating and releasing handle for face.
- Refer to the function **GetWeightings** in **FacialManager.cs** for getting the weightings of blendshapes.

View File

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

View File

@@ -1,755 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.45112008, g: 0.49971223, b: 0.5675026, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 500
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 2
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 4890085278179872738, guid: 139b813ee621cbb41b237fe73214bf9f, type: 2}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &306469291
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 1972517298404456, guid: 628ff83903a43c74ba5c884b8d6d0b59, type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 306469292}
- component: {fileID: 306469293}
m_Layer: 0
m_Name: Avatar Sample
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &306469292
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 4567766556640800, guid: 628ff83903a43c74ba5c884b8d6d0b59, type: 2}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 306469291}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1374042943}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &306469293
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 306469291}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 196084005ab84764aac2e78a079dc66c, type: 3}
m_Name:
m_EditorClassIdentifier:
camera: {fileID: 1387412029}
--- !u!1001 &539581763
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4074961600660305650, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8040272353404943719, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_Name
value: Head Render Scene
objectReference: {fileID: 0}
- target: {fileID: 8040272353404943719, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8952382327610939962, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 7776754447252ff4087ea2ebcc9821d3, type: 3}
--- !u!1 &760214750
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 760214753}
- component: {fileID: 760214752}
- component: {fileID: 760214751}
m_Layer: 0
m_Name: Objects placed in front of user
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!114 &760214751
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 760214750}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 19eff34b54274a84c8b0f87cffbfd76a, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!20 &760214752
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 760214750}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 2147483647
m_RenderingPath: -1
m_TargetTexture: {fileID: 8400000, guid: 600a6f0266444c145945aa3e7f2a29a6, type: 2}
m_TargetDisplay: 0
m_TargetEye: 0
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &760214753
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 760214750}
m_LocalRotation: {x: 0, y: 1, z: 0, w: 0}
m_LocalPosition: {x: 0, y: 0, z: 0.6}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1921226929}
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
--- !u!4 &1374042943 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
m_PrefabInstance: {fileID: 3051409913039127684}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1387412024
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1387412029}
- component: {fileID: 1387412028}
- component: {fileID: 1387412026}
- component: {fileID: 1387412025}
- component: {fileID: 1387412027}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1387412025
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1387412024}
m_Enabled: 1
--- !u!124 &1387412026
Behaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1387412024}
m_Enabled: 1
--- !u!114 &1387412027
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1387412024}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5a2a9c34df4095f47b9ca8f975175f5b, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Device: 0
m_PoseSource: 2
m_PoseProviderComponent: {fileID: 0}
m_TrackingType: 0
m_UpdateType: 0
m_UseRelativeTransform: 0
--- !u!20 &1387412028
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1387412024}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.01
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1387412029
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1387412024}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1921226928
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1921226929}
- component: {fileID: 1921226932}
- component: {fileID: 1921226931}
- component: {fileID: 1921226930}
m_Layer: 0
m_Name: Mirror
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1921226929
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921226928}
m_LocalRotation: {x: -0, y: 1, z: -0, w: 0}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: -1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 760214753}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
--- !u!23 &1921226930
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921226928}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 20c0a6a4ee4540848b1ad902026d6110, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!64 &1921226931
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921226928}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 4
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!33 &1921226932
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921226928}
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &2095842635
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2095842637}
- component: {fileID: 2095842636}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &2095842636
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2095842635}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &2095842637
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2095842635}
m_LocalRotation: {x: -0.008544729, y: -0.21568543, z: 0.9708363, w: -0.10432531}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 24.871, y: -358.205, z: -167.337}
--- !u!1001 &3051409913039127684
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 306469292}
m_Modifications:
- target: {fileID: 3051409913850609593, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalScale.z
value: -1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609593, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.w
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609593, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609593, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609593, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 180
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_RootOrder
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalScale.z
value: -1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalPosition.y
value: -0.04
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalPosition.z
value: -0.158
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609595, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609597, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalScale.z
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609599, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalScale.z
value: -1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609599, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.w
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609599, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609599, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3051409913850609599, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 180
objectReference: {fileID: 0}
- target: {fileID: 3051409913850635163, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_Name
value: Avatar_Shieh_V2
objectReference: {fileID: 0}
- target: {fileID: 3051409913850733890, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850733890, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: NeededToGetData
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850733895, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3051409913850733895, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}
propertyPath: NeededToGetData
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 4e2328178fed81348aec48d0f79c86fa, type: 3}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 139b813ee621cbb41b237fe73214bf9f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -1,71 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.XR.OpenXR;
namespace VIVE
{
namespace FacialTracking.Sample
{
public static class Eye
{
public const int WeightingCount = (int)XrEyeShapeHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC;
private static XrFacialExpressionsHTC EyeExpression_;
private static int LastUpdateFrame = -1;
private static Error LastUpdateResult = Error.FAILED;
private static Dictionary<XrEyeShapeHTC, float> Weightings;
private static float[] blendshapes = new float[60];
static Eye()
{
Weightings = new Dictionary<XrEyeShapeHTC, float>();
for (int i = 0; i < WeightingCount; ++i) Weightings.Add((XrEyeShapeHTC)i, 0.0f);
}
private static bool UpdateData()
{
if (Time.frameCount == LastUpdateFrame) return LastUpdateResult == Error.WORK;
else LastUpdateFrame = Time.frameCount;
EyeExpression_.expressionCount = 60;
EyeExpression_.type = XrStructureType.XR_TYPE_FACIAL_EXPRESSIONS_HTC;
EyeExpression_.blendShapeWeightings = Marshal.AllocCoTaskMem(sizeof(float) * EyeExpression_.expressionCount);
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = feature.xrGetFacialExpressionsHTC(OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle, ref EyeExpression_);
if (res == (int)XrResult.XR_SUCCESS)
{
Marshal.Copy(EyeExpression_.blendShapeWeightings, blendshapes, 0, EyeExpression_.expressionCount);
LastUpdateResult = Error.WORK;
}
else
{
LastUpdateResult = Error.FAILED;
}
return LastUpdateResult == Error.WORK;
}
public static bool GetEyeWeightings(out Dictionary<XrEyeShapeHTC, float> shapes, XrFacialExpressionsHTC expression)
{
for (int i = 0; i < WeightingCount; ++i)
{
Weightings[(XrEyeShapeHTC)(i)] = blendshapes[i];
}
shapes = Weightings;
return true;
}
/// <summary>
/// Gets weighting values from Eye module.
/// </summary>
/// <param name="shapes">Weighting values obtained from Eye module.</param>
/// <returns>Indicates whether the values received are new.</returns>\
[Obsolete("Create FacialManager object and call member function GetWeightings instead")]
public static bool GetEyeWeightings(out Dictionary<XrEyeShapeHTC, float> shapes)
{
UpdateData();
return GetEyeWeightings(out shapes, EyeExpression_);
}
}
}
}

View File

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

View File

@@ -1,32 +0,0 @@
//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace VIVE
{
namespace FacialTracking.Sample
{
public enum EyeShape
{
None = -1,
Eye_Left_Blink = 0,
Eye_Left_Wide,
Eye_Left_Right,
Eye_Left_Left,
Eye_Left_Up,
Eye_Left_Down,
Eye_Right_Blink = 6,
Eye_Right_Wide,
Eye_Right_Right,
Eye_Right_Left,
Eye_Right_Up,
Eye_Right_Down,
Eye_Frown = 12,
Eye_Left_Squeeze,
Eye_Right_Squeeze,
Max = 15,
}
}
}

View File

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

View File

@@ -1,72 +0,0 @@
//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System;
namespace VIVE
{
namespace FacialTracking.Sample
{
[CustomPropertyDrawer(typeof(EyeShapeTable))]
public class EyeShapeTableDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
Rect newFieldPosition = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
newFieldPosition.height = EditorGUIUtility.singleLineHeight;
Rect newLabelPosition = position;
newLabelPosition.width -= newFieldPosition.width;
newLabelPosition.height = EditorGUIUtility.singleLineHeight;
SerializedProperty propSkinedMesh = property.FindPropertyRelative("skinnedMeshRenderer");
SerializedProperty propEyeShapes = property.FindPropertyRelative("eyeShapes");
EditorGUI.PropertyField(newFieldPosition, propSkinedMesh, GUIContent.none);
newFieldPosition.y += EditorGUIUtility.singleLineHeight;
SkinnedMeshRenderer skinnedMesh = propSkinedMesh.objectReferenceValue as SkinnedMeshRenderer;
if (skinnedMesh != null && skinnedMesh.sharedMesh.blendShapeCount > 0)
{
if (propEyeShapes.arraySize != skinnedMesh.sharedMesh.blendShapeCount)
{
propEyeShapes.arraySize = skinnedMesh.sharedMesh.blendShapeCount;
for (int i = 0; i < skinnedMesh.sharedMesh.blendShapeCount; ++i)
{
SerializedProperty propEyeShape = propEyeShapes.GetArrayElementAtIndex(i);
string elementName = skinnedMesh.sharedMesh.GetBlendShapeName(i);
propEyeShape.intValue = (int)XrEyeShapeHTC.XR_EYE_SHAPE_NONE_HTC;
foreach (XrEyeShapeHTC EyeShape in (XrEyeShapeHTC[])Enum.GetValues(typeof(XrEyeShapeHTC)))
{
if (elementName == EyeShape.ToString())
propEyeShape.intValue = (int)EyeShape;
}
}
}
for (int i = 0; i < skinnedMesh.sharedMesh.blendShapeCount; ++i)
{
SerializedProperty propEyeShape = propEyeShapes.GetArrayElementAtIndex(i);
newLabelPosition.y = newFieldPosition.y;
string elementName = skinnedMesh.sharedMesh.GetBlendShapeName(i);
EditorGUI.LabelField(newLabelPosition, " " + elementName);
EditorGUI.PropertyField(newFieldPosition, propEyeShape, GUIContent.none);
newFieldPosition.y += EditorGUIUtility.singleLineHeight;
}
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
int LineCount = 1;
SerializedProperty propSkinedMesh = property.FindPropertyRelative("skinnedMeshRenderer");
SkinnedMeshRenderer skinnedMesh = propSkinedMesh.objectReferenceValue as SkinnedMeshRenderer;
if (skinnedMesh != null) LineCount += skinnedMesh.sharedMesh.blendShapeCount;
return EditorGUIUtility.singleLineHeight * LineCount;
}
}
}
}
#endif

View File

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

View File

@@ -1,100 +0,0 @@
//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
using System;
using UnityEngine;
using UnityEngine.XR.OpenXR;
namespace VIVE
{
namespace FacialTracking.Sample
{
public class Eye_Framework : MonoBehaviour
{
public enum FrameworkStatus { STOP, START, WORKING, ERROR, NOT_SUPPORT }
/// <summary>
/// The status of the Eye engine.
/// </summary>
public static FrameworkStatus Status { get; protected set; }
/// <summary>
/// Whether to enable Eye module.
/// </summary>
public bool EnableEye = true;
private static Eye_Framework Mgr = null;
public static Eye_Framework Instance
{
get
{
if (Mgr == null)
{
Mgr = FindObjectOfType<Eye_Framework>();
}
if (Mgr == null)
{
Debug.LogError("Eye_Framework not found");
}
return Mgr;
}
}
void Start()
{
StartFramework();
}
void OnDestroy()
{
StopFramework();
}
[Obsolete("Create FacialManager object and call member function StartFramework instead")]
public void StartFramework()
{
if (!EnableEye) return;
if (Status == FrameworkStatus.WORKING || Status == FrameworkStatus.NOT_SUPPORT) return;
XrFacialTrackerCreateInfoHTC m_expressioncreateInfo = new XrFacialTrackerCreateInfoHTC(
XrStructureType.XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC,
IntPtr.Zero,
XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC);
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = feature.xrCreateFacialTrackerHTC(m_expressioncreateInfo, out OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle);
if (res == (int)XrResult.XR_SUCCESS || res == (int)XrResult.XR_SESSION_LOSS_PENDING)
{
Debug.Log("Initial Eye success : " + res);
Status = FrameworkStatus.WORKING;
}
else
{
Debug.LogError("Initial Eye fail : " + res);
Status = FrameworkStatus.ERROR;
}
}
[Obsolete("Create FacialManager object and call member function StopFramework instead")]
public void StopFramework()
{
if (Status != FrameworkStatus.NOT_SUPPORT)
{
if (Status != FrameworkStatus.STOP)
{
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = feature.xrDestroyFacialTrackerHTC(OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle);
if (res == (int)XrResult.XR_SUCCESS)
{
Debug.Log("Release Eye engine success : " + res);
}
else
{
Debug.LogError("Release Eye engine fail : " + res);
}
}
else
{
Debug.Log("Stop Eye Framework : module not on");
}
}
Status = FrameworkStatus.STOP;
}
}
}
}

View File

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

View File

@@ -1,234 +0,0 @@
//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
using System;
using System.Collections.Generic;
using UnityEngine;
namespace VIVE
{
namespace FacialTracking.Sample
{
[Serializable]
public class EyeShapeTable
{
public SkinnedMeshRenderer skinnedMeshRenderer;
public EyeShape[] eyeShapes;
}
public class AvatarEyeSample : MonoBehaviour
{
[SerializeField] private Transform[] EyesModels = new Transform[0];
[SerializeField] private List<EyeShapeTable> EyeShapeTables;
/// <summary>
/// Customize this curve to fit the blend shapes of your avatar.
/// </summary>
[SerializeField] private AnimationCurve EyebrowAnimationCurveUpper;
/// <summary>
/// Customize this curve to fit the blend shapes of your avatar.
/// </summary>
[SerializeField] private AnimationCurve EyebrowAnimationCurveLower;
/// <summary>
/// Customize this curve to fit the blend shapes of your avatar.
/// </summary>
[SerializeField] private AnimationCurve EyebrowAnimationCurveHorizontal;
public bool NeededToGetData = true;
private Dictionary<XrEyeShapeHTC, float> EyeWeightings = new Dictionary<XrEyeShapeHTC, float>();
//Map Openxr eye shape to Avatar eye blendshape
private static Dictionary<EyeShape, XrEyeShapeHTC> ShapeMap;
private AnimationCurve[] EyebrowAnimationCurves = new AnimationCurve[(int)EyeShape.Max];
private GameObject[] EyeAnchors;
private const int NUM_OF_EYES = 2;
private static XrFacialExpressionsHTC EyeExpression;
private FacialManager facialManager = new FacialManager();
static AvatarEyeSample()
{
ShapeMap = new Dictionary<EyeShape, XrEyeShapeHTC>();
ShapeMap.Add(EyeShape.Eye_Left_Blink, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_BLINK_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Wide, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_WIDE_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Blink, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_BLINK_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Wide, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_WIDE_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Squeeze, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_SQUEEZE_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Squeeze, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_SQUEEZE_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Down, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_DOWN_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Down, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_DOWN_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Left, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_OUT_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Left, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_IN_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Right, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_IN_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Right, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_OUT_HTC);
ShapeMap.Add(EyeShape.Eye_Left_Up, XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_UP_HTC);
ShapeMap.Add(EyeShape.Eye_Right_Up, XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_UP_HTC);
}
private void Start()
{
facialManager.StartFramework(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC);
SetEyesModels(EyesModels[0], EyesModels[1]);
SetEyeShapeTables(EyeShapeTables);
AnimationCurve[] curves = new AnimationCurve[(int)EyeShape.Max];
for (int i = 0; i < EyebrowAnimationCurves.Length; ++i)
{
if (i == (int)EyeShape.Eye_Left_Up || i == (int)EyeShape.Eye_Right_Up) curves[i] = EyebrowAnimationCurveUpper;
else if (i == (int)EyeShape.Eye_Left_Down || i == (int)EyeShape.Eye_Right_Down) curves[i] = EyebrowAnimationCurveLower;
else curves[i] = EyebrowAnimationCurveHorizontal;
}
SetEyeShapeAnimationCurves(curves);
}
private void Update()
{
if (NeededToGetData)
{
facialManager.GetWeightings(out EyeWeightings);
UpdateEyeShapes(EyeWeightings);
Vector3 GazeDirectionCombinedLocal = Vector3.zero;
if (EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_IN_HTC] > EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_OUT_HTC])
{
GazeDirectionCombinedLocal.x = -1 * EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_IN_HTC];
}
else
{
GazeDirectionCombinedLocal.x = EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_OUT_HTC];
}
if (EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_UP_HTC] > EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_DOWN_HTC])
{
GazeDirectionCombinedLocal.y = EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_UP_HTC];
}
else
{
GazeDirectionCombinedLocal.y = -EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_LEFT_DOWN_HTC];
}
GazeDirectionCombinedLocal.z = (float)1.0;
Vector3 target = EyeAnchors[0].transform.TransformPoint(GazeDirectionCombinedLocal);
EyesModels[0].LookAt(target);
if (EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_IN_HTC] > EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_OUT_HTC])
{
GazeDirectionCombinedLocal.x = EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_IN_HTC];
}
else
{
GazeDirectionCombinedLocal.x = -1 * EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_OUT_HTC];
}
if (EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_UP_HTC] > EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_DOWN_HTC])
{
GazeDirectionCombinedLocal.y = EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_UP_HTC];
}
else
{
GazeDirectionCombinedLocal.y = -EyeWeightings[XrEyeShapeHTC.XR_EYE_EXPRESSION_RIGHT_DOWN_HTC];
}
GazeDirectionCombinedLocal.z = (float)1.0;
target = EyeAnchors[1].transform.TransformPoint(GazeDirectionCombinedLocal);
EyesModels[1].LookAt(target);
}
}
private void OnDestroy()
{
facialManager.StopFramework(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC);
DestroyEyeAnchors();
}
public void SetEyesModels(Transform leftEye, Transform rightEye)
{
if (leftEye != null && rightEye != null)
{
EyesModels = new Transform[NUM_OF_EYES] { leftEye, rightEye };
DestroyEyeAnchors();
CreateEyeAnchors();
}
}
public void SetEyeShapeTables(List<EyeShapeTable> eyeShapeTables)
{
bool valid = true;
if (eyeShapeTables == null)
{
valid = false;
}
else
{
for (int table = 0; table < eyeShapeTables.Count; ++table)
{
if (eyeShapeTables[table].skinnedMeshRenderer == null)
{
valid = false;
break;
}
for (int shape = 0; shape < eyeShapeTables[table].eyeShapes.Length; ++shape)
{
EyeShape eyeShape = eyeShapeTables[table].eyeShapes[shape];
if (eyeShape > EyeShape.Max || eyeShape < 0)
{
valid = false;
break;
}
}
}
}
if (valid)
EyeShapeTables = eyeShapeTables;
}
public void SetEyeShapeAnimationCurves(AnimationCurve[] eyebrowAnimationCurves)
{
if (eyebrowAnimationCurves.Length == (int)EyeShape.Max)
EyebrowAnimationCurves = eyebrowAnimationCurves;
}
public void UpdateEyeShapes(Dictionary<XrEyeShapeHTC, float> eyeWeightings)
{
foreach (var table in EyeShapeTables)
RenderModelEyeShape(table, eyeWeightings);
}
private void RenderModelEyeShape(EyeShapeTable eyeShapeTable, Dictionary<XrEyeShapeHTC, float> weighting)
{
for (int i = 0; i < eyeShapeTable.eyeShapes.Length; ++i)
{
EyeShape eyeShape = eyeShapeTable.eyeShapes[i];
if (eyeShape > EyeShape.Max || eyeShape < 0 || !ShapeMap.ContainsKey(eyeShape)) continue;
XrEyeShapeHTC xreyeshape = ShapeMap[eyeShape];
if (eyeShape == EyeShape.Eye_Left_Blink || eyeShape == EyeShape.Eye_Right_Blink)
{
eyeShapeTable.skinnedMeshRenderer.SetBlendShapeWeight(i, weighting[xreyeshape] * 100f);
}
else
{
AnimationCurve curve = EyebrowAnimationCurves[(int)eyeShape];
eyeShapeTable.skinnedMeshRenderer.SetBlendShapeWeight(i, curve.Evaluate(weighting[xreyeshape]) * 100f);
}
}
}
private void CreateEyeAnchors()
{
EyeAnchors = new GameObject[NUM_OF_EYES];
for (int i = 0; i < NUM_OF_EYES; ++i)
{
EyeAnchors[i] = new GameObject();
EyeAnchors[i].name = "EyeAnchor_" + i;
EyeAnchors[i].transform.SetParent(gameObject.transform);
EyeAnchors[i].transform.localPosition = EyesModels[i].localPosition;
EyeAnchors[i].transform.localRotation = EyesModels[i].localRotation;
EyeAnchors[i].transform.localScale = EyesModels[i].localScale;
}
}
private void DestroyEyeAnchors()
{
if (EyeAnchors != null)
{
foreach (var obj in EyeAnchors)
if (obj != null) Destroy(obj);
}
}
}
}
}

View File

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

View File

@@ -1,35 +0,0 @@
//========= Copyright 2018, HTC Corporation. All rights reserved. ===========
using System.Runtime.InteropServices;
using UnityEngine;
namespace VIVE
{
namespace FacialTracking.Sample
{
/// <summary>
/// A very basic mirror.
/// </summary>
[RequireComponent(typeof(Camera))]
public class MirrorCameraSample_Eye : MonoBehaviour
{
private const float Distance = 0.6f;
private void Update()
{
if (Eye_Framework.Status != Eye_Framework.FrameworkStatus.WORKING) return;
}
private void Release()
{
}
private void SetMirroTransform()
{
transform.position = Camera.main.transform.position + Camera.main.transform.forward * Distance;
transform.position = new Vector3(transform.position.x, Camera.main.transform.position.y, transform.position.z);
transform.LookAt(Camera.main.transform);
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
}
}
}
}

View File

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

View File

@@ -1,22 +0,0 @@
using UnityEngine;
namespace VIVE.FacialTracking.Sample
{
public class FollowCamera : MonoBehaviour
{
// Start is called before the first frame update
public new Transform camera;
private Vector3 offset;
void Start()
{
this.transform.position = new Vector3(camera.position.x, camera.position.y, camera.position.z + 1);
}
// Update is called once per frame
void Update()
{
this.transform.position = new Vector3(this.transform.position.x, camera.position.y, this.transform.position.z);
}
}
}

View File

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

View File

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

View File

@@ -1,71 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.XR.OpenXR;
namespace VIVE
{
namespace FacialTracking.Sample
{
public class Lip
{
public const int WeightingCount = (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC;
private static int LastUpdateFrame = -1;
private static Error LastUpdateResult = Error.FAILED;
private static Dictionary<XrLipShapeHTC, float> Weightings;
private static float[] blendshapes = new float[60];
private static XrFacialExpressionsHTC LipExpression;
static Lip()
{
Weightings = new Dictionary<XrLipShapeHTC, float>();
for (int i = 0; i < WeightingCount; ++i) Weightings.Add((XrLipShapeHTC)i, 0.0f);
}
private static bool UpdateData()
{
if (Time.frameCount == LastUpdateFrame) return LastUpdateResult == Error.WORK;
else LastUpdateFrame = Time.frameCount;
LipExpression.expressionCount = 60;
LipExpression.type = XrStructureType.XR_TYPE_FACIAL_EXPRESSIONS_HTC;
LipExpression.blendShapeWeightings = Marshal.AllocCoTaskMem(sizeof(float)* LipExpression.expressionCount);
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = feature.xrGetFacialExpressionsHTC(OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle_Lip, ref LipExpression);
if(res == (int)XrResult.XR_SUCCESS)
{
LastUpdateResult = Error.WORK;
Marshal.Copy(LipExpression.blendShapeWeightings, blendshapes,0, LipExpression.expressionCount);
for (int i = 0; i < WeightingCount; ++i)
{
Weightings[(XrLipShapeHTC)(i)] = blendshapes[i];
}
}
else
{
LastUpdateResult = Error.FAILED;
}
return LastUpdateResult == Error.WORK;
}
/// <summary>
/// Gets weighting values from Lip module.
/// </summary>
/// <param name="shapes">Weighting values obtained from Lip module.</param>
/// <returns>Indicates whether the values received are new.</returns>
[Obsolete("Create FacialManager object and call member function GetWeightings instead")]
public static bool GetLipWeightings(out Dictionary<XrLipShapeHTC, float> shapes)
{
bool update = UpdateData();
shapes = Weightings;
return update;
}
}
}
}

View File

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

View File

@@ -1,69 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using System;
using System.Runtime.InteropServices;
namespace VIVE
{
namespace FacialTracking.Sample
{
public enum LipShape
{
None = -1,
Jaw_Right = 0,
Jaw_Left = 1,
Jaw_Forward = 2,
Jaw_Open = 3,
Mouth_Ape_Shape = 4,
Mouth_Upper_Right = 5,
Mouth_Upper_Left = 6,
Mouth_Lower_Right = 7,
Mouth_Lower_Left = 8,
Mouth_Upper_Overturn = 9,
Mouth_Lower_Overturn = 10,
Mouth_Pout = 11,
Mouth_Smile_Right = 12,
Mouth_Smile_Left = 13,
Mouth_Sad_Right = 14,
Mouth_Sad_Left = 15,
Cheek_Puff_Right = 16,
Cheek_Puff_Left = 17,
Cheek_Suck = 18,
Mouth_Upper_UpRight = 19,
Mouth_Upper_UpLeft = 20,
Mouth_Lower_DownRight = 21,
Mouth_Lower_DownLeft = 22,
Mouth_Upper_Inside = 23,
Mouth_Lower_Inside = 24,
Mouth_Lower_Overlay = 25,
Tongue_LongStep1 = 26,
Tongue_LongStep2 = 32,
Tongue_Down = 30,
Tongue_Up = 29,
Tongue_Right = 28,
Tongue_Left = 27,
Tongue_Roll = 31,
Tongue_UpLeft_Morph = 34,
Tongue_UpRight_Morph = 33,
Tongue_DownLeft_Morph = 36,
Tongue_DownRight_Morph = 35,
Max = 37,
}
[StructLayout(LayoutKind.Sequential)]
public struct PredictionData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 60)]
public float[] blend_shape_weight;
};
[StructLayout(LayoutKind.Sequential)]
public struct LipData
{
public int frame;
public int time;
public IntPtr image;
public PredictionData prediction_data;
};
}
}

View File

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

View File

@@ -1,73 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System;
namespace VIVE
{
namespace FacialTracking.Sample
{
[CustomPropertyDrawer(typeof(LipShapeTable))]
public class LipShapeTableDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
Rect newFieldPosition = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
newFieldPosition.height = EditorGUIUtility.singleLineHeight;
Rect newLabelPosition = position;
newLabelPosition.width -= newFieldPosition.width;
newLabelPosition.height = newFieldPosition.height;
SerializedProperty propSkinedMesh = property.FindPropertyRelative("skinnedMeshRenderer");
SerializedProperty propLipShapes = property.FindPropertyRelative("lipShapes");
EditorGUI.PropertyField(newFieldPosition, propSkinedMesh, GUIContent.none);
newFieldPosition.y += EditorGUIUtility.singleLineHeight;
SkinnedMeshRenderer skinnedMesh = propSkinedMesh.objectReferenceValue as SkinnedMeshRenderer;
if (skinnedMesh != null && skinnedMesh.sharedMesh.blendShapeCount > 0)
{
if (propLipShapes.arraySize != skinnedMesh.sharedMesh.blendShapeCount)
{
propLipShapes.arraySize = skinnedMesh.sharedMesh.blendShapeCount;
for (int i = 0; i < skinnedMesh.sharedMesh.blendShapeCount; ++i)
{
SerializedProperty propLipShape = propLipShapes.GetArrayElementAtIndex(i);
string elementName = skinnedMesh.sharedMesh.GetBlendShapeName(i);
propLipShape.intValue = (int)XrLipShapeHTC.XR_LIP_SHAPE_NONE_HTC;
foreach (XrLipShapeHTC lipShape in (XrLipShapeHTC[])Enum.GetValues(typeof(XrLipShapeHTC)))
{
if (elementName == lipShape.ToString())
propLipShape.intValue = (int)lipShape;
}
}
}
for (int i = 0; i < skinnedMesh.sharedMesh.blendShapeCount; ++i)
{
SerializedProperty propLipShape = propLipShapes.GetArrayElementAtIndex(i);
newLabelPosition.y = newFieldPosition.y;
string elementName = skinnedMesh.sharedMesh.GetBlendShapeName(i);
EditorGUI.LabelField(newLabelPosition, " " + elementName);
EditorGUI.PropertyField(newFieldPosition, propLipShape, GUIContent.none);
newFieldPosition.y += EditorGUIUtility.singleLineHeight;
}
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
int LineCount = 1;
SerializedProperty propSkinedMesh = property.FindPropertyRelative("skinnedMeshRenderer");
SkinnedMeshRenderer skinnedMesh = propSkinedMesh.objectReferenceValue as SkinnedMeshRenderer;
if (skinnedMesh != null) LineCount += skinnedMesh.sharedMesh.blendShapeCount;
return EditorGUIUtility.singleLineHeight * LineCount;
}
}
}
}
#endif

View File

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

View File

@@ -1,103 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using System;
using UnityEngine;
using UnityEngine.XR.OpenXR;
namespace VIVE
{
namespace FacialTracking.Sample
{
public class Lip_Framework : MonoBehaviour
{
public enum FrameworkStatus { STOP, START, WORKING, ERROR }
/// <summary>
/// The status of the Lip engine.
/// </summary>
public static FrameworkStatus Status { get; protected set; }
/// <summary>
/// Whether to enable Lip module.
/// </summary>
public bool EnableLip = true;
private static Lip_Framework Mgr = null;
public static Lip_Framework Instance
{
get
{
if (Mgr == null)
{
Mgr = FindObjectOfType<Lip_Framework>();
}
if (Mgr == null)
{
Debug.LogError("Lip_Framework not found");
}
return Mgr;
}
}
void Start()
{
StartFramework();
}
void OnDestroy()
{
StopFramework();
}
[Obsolete("Create FacialManager object and call member function StartFramework instead")]
private void StartFramework()
{
if (!EnableLip) return;
if (Status == FrameworkStatus.WORKING) return;
Status = FrameworkStatus.START;
Debug.Log("Starting to Initial Lip Engine");
XrFacialTrackerCreateInfoHTC m_expressioncreateInfo = new XrFacialTrackerCreateInfoHTC(
XrStructureType.XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC,
IntPtr.Zero,
XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC);
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = (int)feature.xrCreateFacialTrackerHTC(m_expressioncreateInfo, out OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle_Lip);
if (res == (int)XrResult.XR_SUCCESS || res == (int)XrResult.XR_SESSION_LOSS_PENDING)
{
Debug.Log("Initial Lip Engine :" + res);
Status = FrameworkStatus.WORKING;
}
else
{
Debug.LogError("Initial Lip Engine :" + res);
Status = FrameworkStatus.ERROR;
}
}
[Obsolete("Create FacialManager object and call member function StopFramework instead")]
public void StopFramework()
{
if (Status != FrameworkStatus.STOP)
{
var feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
int res = feature.xrDestroyFacialTrackerHTC(OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>().m_expressionHandle_Lip);
if (res == (int)XrResult.XR_SUCCESS)
{
Debug.Log("Release Lip Engine : " + res);
}
else
{
Debug.LogError("Release Lip Engine : " + res);
}
}
else
{
Debug.Log("Stop Lip Framework : module not on");
}
Status = FrameworkStatus.STOP;
}
}
}
}

View File

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

View File

@@ -1,93 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using System;
using System.Collections.Generic;
using UnityEngine;
namespace VIVE
{
namespace FacialTracking.Sample
{
[Serializable]
public class LipShapeTable
{
public SkinnedMeshRenderer skinnedMeshRenderer;
public XrLipShapeHTC[] lipShapes;
}
public class AvatarLipSample : MonoBehaviour
{
[SerializeField] private List<LipShapeTable> LipShapeTables;
public bool NeededToGetData = true;
private Dictionary<XrLipShapeHTC, float> LipWeightings;
private FacialManager facialManager = new FacialManager();
private void Start()
{
facialManager.StartFramework(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC);
SetLipShapeTables(LipShapeTables);
}
private void Update()
{
if (NeededToGetData)
{
facialManager.GetWeightings(out LipWeightings);
//Lip.GetLipWeightings(out LipWeightings);
UpdateLipShapes(LipWeightings);
}
}
public void SetLipShapeTables(List<LipShapeTable> lipShapeTables)
{
bool valid = true;
if (lipShapeTables == null)
{
valid = false;
}
else
{
for (int table = 0; table < lipShapeTables.Count; ++table)
{
if (lipShapeTables[table].skinnedMeshRenderer == null)
{
valid = false;
break;
}
for (int shape = 0; shape < lipShapeTables[table].lipShapes.Length; ++shape)
{
XrLipShapeHTC lipShape = lipShapeTables[table].lipShapes[shape];
if (lipShape > XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC || lipShape < 0)
{
valid = false;
break;
}
}
}
}
if (valid)
LipShapeTables = lipShapeTables;
}
public void UpdateLipShapes(Dictionary<XrLipShapeHTC, float> lipWeightings)
{
foreach (var table in LipShapeTables)
RenderModelLipShape(table, lipWeightings);
}
private void RenderModelLipShape(LipShapeTable lipShapeTable, Dictionary<XrLipShapeHTC, float> weighting)
{
for (int i = 0; i < lipShapeTable.lipShapes.Length; i++)
{
int targetIndex = (int)lipShapeTable.lipShapes[i];
if (targetIndex > (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC || targetIndex < 0) continue;
lipShapeTable.skinnedMeshRenderer.SetBlendShapeWeight(i, weighting[(XrLipShapeHTC)targetIndex] * 100);
}
}
private void OnDestroy()
{
facialManager.StopFramework(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC);
}
}
}
}

View File

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

View File

@@ -1,32 +0,0 @@
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
using UnityEngine;
namespace VIVE
{
namespace FacialTracking.Sample
{
/// <summary>
/// A very basic mirror.
/// </summary>
[RequireComponent(typeof(Camera))]
public class MirrorCameraSample_Lip : MonoBehaviour
{
private const float Distance = 0.6f;
private void Update()
{
if (Lip_Framework.Status != Lip_Framework.FrameworkStatus.WORKING) return;
SetMirroTransform();
}
private void SetMirroTransform()
{
transform.position = Camera.main.transform.position + Camera.main.transform.forward * Distance;
transform.position = new Vector3(transform.position.x, Camera.main.transform.position.y, transform.position.z);
transform.LookAt(Camera.main.transform);
transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0);
}
}
}
}

View File

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

View File

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

View File

@@ -1,216 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using System;
namespace VIVE.FacialTracking
{
public class FacialManager
{
private class FacialData
{
public bool isStarted = false;
public XrFacialTrackingTypeHTC trackingType;
public bool isActive;
public ulong trackerHandle;
public int updatedFrame = -1;
public Dictionary<XrEyeShapeHTC, float> eyeWeightings = new Dictionary<XrEyeShapeHTC, float>();
public Dictionary<XrLipShapeHTC, float> LipWeightings = new Dictionary<XrLipShapeHTC, float>();
public float[] blendshapes;
public bool isCreated { get { return trackerHandle != default; } }
public FacialData(XrFacialTrackingTypeHTC type)
{
trackingType = type;
for (int i = 0; i < (int)XrEyeShapeHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC; ++i) eyeWeightings.Add((XrEyeShapeHTC)i, 0.0f);
for (int i = 0; i < (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC; ++i) LipWeightings.Add((XrLipShapeHTC)i, 0.0f);
int shapeSize = type == XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC
? (int)XrEyeShapeHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC : (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC;
blendshapes = new float[shapeSize];
}
public void ClearData()
{
Array.Clear(blendshapes, 0, blendshapes.Length);
eyeWeightings.Clear();
LipWeightings.Clear();
}
}
private FacialData eyeFacialData = new FacialData(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC);
private FacialData lipFacialData = new FacialData(XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC);
private VIVE_FacialTracking_OpenXR_API feature;
private static bool isInitialized;
private static bool isSystemSupportEye;
private static bool isSystemSupportLip;
private FacialData getFacialData(XrFacialTrackingTypeHTC type)
{
if (type == XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC)
return eyeFacialData;
else
return lipFacialData;
}
private void OnFeatureSessionCreate(ulong xrSession)
{
TryCreateFacialTracker(eyeFacialData);
TryCreateFacialTracker(lipFacialData);
}
private void OnFeatureSessionDestroy(ulong xrSession)
{
TryDestroyFacialTracker(eyeFacialData);
TryDestroyFacialTracker(lipFacialData);
}
private void OnFeatureSystemChange(ulong systemId)
{
UpdateSystemSupported();
}
private void UpdateSystemSupported()
{
if (feature == null || !feature.IsEnabledAndInitialized)
{
isSystemSupportEye = false;
isSystemSupportLip = false;
}
else
{
feature.SystemSupportsFacialTracking(out var result,out isSystemSupportEye,out isSystemSupportLip);
if (result != XrResult.XR_SUCCESS)
{
Debug.LogWarning("Fail SystemSupportsHandTracking: " + result);
}
if (!isSystemSupportEye)
{
UnityEngine.Debug.Log("Initial eyetracking failed , the device may not support EyeExpression");
}
if (!isSystemSupportLip)
{
UnityEngine.Debug.Log("Initial liptracking failed , the device may not support LipExpression");
}
}
}
public bool Initialize()
{
if(feature == null)
feature = OpenXRSettings.Instance.GetFeature<VIVE_FacialTracking_OpenXR_API>();
if (!isInitialized)
{
if (feature != null)
{
feature.onSessionCreate += OnFeatureSessionCreate;
feature.onSessionDestroy += OnFeatureSessionDestroy;
feature.onSystemChange += OnFeatureSystemChange;
}
if (feature != null && feature.IsEnabledAndInitialized)
{
UpdateSystemSupported();
isInitialized = true;
}
}
return isInitialized;
}
private bool TryCreateFacialTracker(FacialData facialData)
{
if (!facialData.isStarted) return false;
if (!Initialize()) { return false; }
if (facialData.trackingType == XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC && !isSystemSupportEye) { return false; }
if (facialData.trackingType == XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC && !isSystemSupportLip) { return false; }
if (!feature.IsSessionCreated) { return false; }
if (!facialData.isCreated)
{
if (!feature.TryCreateFacialTracker(facialData.trackingType, out facialData.trackerHandle, out var result))
{
facialData.trackerHandle = default;
Debug.LogWarning("Fail CreateFacialTracker: " + result);
}
}
return facialData.isCreated;
}
private void TryDestroyFacialTracker(FacialData facialData)
{
if (!facialData.isCreated) { return; }
if (!Initialize()) { return; }
if(!feature.TryDestroFacialTracker(facialData.trackerHandle, out var res))
{
Debug.LogWarning("Fail DestroyFacialTracker: " + res);
}
else
{
Debug.Log("Success DestroyFacialTracker: " + res);
}
facialData.trackerHandle = default;
facialData.ClearData();
}
private void TryGetFacialData(FacialData facialData)
{
if(facialData.isCreated)
{
if(facialData.updatedFrame != Time.frameCount)
{
int maxExpressionCount = facialData.trackingType == XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC
? (int)XrEyeShapeHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC : (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC;
facialData.updatedFrame = Time.frameCount;
if (!feature.TryGetFacialData(
facialData.trackerHandle,
out facialData.isActive,
maxExpressionCount,
out var result,
facialData.blendshapes))
{
facialData.isActive = false;
Debug.LogWarning("Fail TryGetFacialData: " + result);
}
}
}
}
public void StartFramework(XrFacialTrackingTypeHTC type)
{
var facialdata = getFacialData(type);
facialdata.isStarted = true;
TryCreateFacialTracker(facialdata);
}
public void StopFramework(XrFacialTrackingTypeHTC type)
{
var facialdata = getFacialData(type);
facialdata.isStarted = false;
TryDestroyFacialTracker(facialdata);
}
public bool GetWeightings<T>(out Dictionary<T, float> shapes)
{
if (typeof(T) == typeof(XrEyeShapeHTC))
{
TryGetFacialData(eyeFacialData);
for (int i = 0; i < (int)XrEyeShapeHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC; ++i)
{
eyeFacialData.eyeWeightings[(XrEyeShapeHTC)i] = eyeFacialData.blendshapes[i];
}
shapes = (Dictionary<T, float>)(System.Object)(eyeFacialData.eyeWeightings);
return true;
}
else if (typeof(T) == typeof(XrLipShapeHTC))
{
TryGetFacialData(lipFacialData);
for (int i = 0; i < (int)XrLipShapeHTC.XR_LIP_SHAPE_MAX_ENUM_HTC; ++i)
{
lipFacialData.LipWeightings[(XrLipShapeHTC)i] = lipFacialData.blendshapes[i];
}
shapes = (Dictionary<T, float>)(System.Object)(lipFacialData.LipWeightings);
return true;
}
else
{
shapes = default;
return false;
}
}
}
}

View File

@@ -1,192 +0,0 @@
using System;
using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine.XR.OpenXR.Features;
#if UNITY_EDITOR
using UnityEditor.XR.OpenXR.Features;
#endif
namespace VIVE
{
namespace FacialTracking
{
#if UNITY_EDITOR
[OpenXRFeature(UiName = "Facial Tracking",
BuildTargetGroups = new[] { BuildTargetGroup.Standalone },
Company = "HTC",
Desc = "Facial Tracking OpenXR Feature",
DocumentationLink = "https://developer.vive.com/resources/openxr/openxr-pcvr/tutorials/unity/integrate-facial-tracking-your-avatar/",
OpenxrExtensionStrings = "XR_HTC_facial_tracking",
Version = "0.0.1",
FeatureId = featureId)]
#endif
public class VIVE_FacialTracking_OpenXR_API : OpenXRFeature
{
/// <summary>
/// The feature id string. This is used to give the feature a well known id for reference.
/// </summary>
public const string featureId = "com.htc.openxr.facialtracking.feature";
private ulong m_XrInstance;
private ulong m_XrSession;
private ulong m_systemid;
[Obsolete] XrSystemProperties systemProperties;
[Obsolete] public ulong m_expressionHandle;
[Obsolete] public ulong m_expressionHandle_Lip;
public bool IsInitialized { get { return m_xrGetSystemProperties != null; } }
public bool IsEnabledAndInitialized { get { return enabled && IsInitialized; } }
public bool IsSessionCreated { get { return XrSession != default; } }
public ulong XrInstance { get { return m_XrInstance; } }
public ulong XrSession { get { return m_XrSession; } }
public ulong SystemId { get { return m_systemid; } }
public event Action<ulong> onSessionCreate;
public event Action<ulong> onSessionDestroy;
public event Action<ulong> onSystemChange;
/// <inheritdoc />
protected override bool OnInstanceCreate(ulong xrInstance)
{
UnityEngine.Debug.Log($"OnInstanceCreate({xrInstance:X})");
m_XrInstance = xrInstance;
return GetXrFunctionDelegates(xrInstance);
}
/// <inheritdoc />
protected override void OnInstanceDestroy(ulong xrInstance)
{
UnityEngine.Debug.Log($"OnInstanceDestroy({xrInstance:X})");
m_XrInstance = default;
}
protected override void OnSessionCreate(ulong xrSession)
{
UnityEngine.Debug.Log($"OnSessionCreate({xrSession:X})");
m_XrSession = xrSession;
try { onSessionCreate?.Invoke(xrSession); }
catch (Exception e) { UnityEngine.Debug.LogError(e); }
}
protected override void OnSystemChange(ulong xrSystem)
{
UnityEngine.Debug.Log($"OnSystemChange({xrSystem:X})");
m_systemid = xrSystem;
try { onSystemChange?.Invoke(xrSystem); }
catch (Exception e) { UnityEngine.Debug.LogError(e); }
}
protected override void OnSessionDestroy(ulong xrSession)
{
UnityEngine.Debug.Log($"OnSessionDestroy({xrSession:X})");
m_XrSession = default;
try { onSessionDestroy?.Invoke(xrSession); }
catch (Exception e) { UnityEngine.Debug.LogError(e); }
}
private bool GetXrFunctionDelegates(ulong xrInstance)
{
if (xrGetInstanceProcAddr == null || xrGetInstanceProcAddr == IntPtr.Zero)
UnityEngine.Debug.LogError("xrGetInstanceProcAddr is null");
// Get delegate of xrGetInstanceProcAddr.
var xrGetProc = Marshal.GetDelegateForFunctionPointer<xrGetInstanceProcDelegate>(xrGetInstanceProcAddr);
// Get delegate of other OpenXR functions using xrGetInstanceProcAddr.
if (!MarshelFunc(xrInstance, xrGetProc, "xrGetSystemProperties", ref m_xrGetSystemProperties)) { return false; }
if (!MarshelFunc(xrInstance, xrGetProc, "xrCreateFacialTrackerHTC", ref m_xrCreateFacialTrackerHTC)) { return false; }
if (!MarshelFunc(xrInstance, xrGetProc, "xrDestroyFacialTrackerHTC", ref m_xrDestroyFacialTrackerHTC)) { return false; }
if (!MarshelFunc(xrInstance, xrGetProc, "xrGetFacialExpressionsHTC", ref m_xrGetFacialExpressionsHTC)) { return false; }
return true;
}
private static bool MarshelFunc<T>(ulong instance, xrGetInstanceProcDelegate instanceProc, string funcName, ref T func, bool verbose = true)
where T : Delegate
{
if (instanceProc(instance, funcName, out var fp) != 0)
{
if (verbose)
{
UnityEngine.Debug.LogError("Fail getting function " + funcName);
}
return false;
}
func = Marshal.GetDelegateForFunctionPointer<T>(fp);
return true;
}
delegate int XrGetInstanceProcAddrDelegate(ulong instance, string name, out IntPtr function);
XrGetInstanceProcAddrDelegate m_XrGetInstanceProcAddr;
delegate int xrGetSystemPropertiesDelegate(ulong instance, ulong systemId, ref XrSystemProperties properties);
xrGetSystemPropertiesDelegate m_xrGetSystemProperties;
public int xrGetSystemProperties(ref XrSystemProperties properties) =>
m_xrGetSystemProperties(m_XrInstance, m_systemid, ref properties);
public int xrGetSystemProperties(ulong instance, ulong systemId, ref XrSystemProperties properties) =>
m_xrGetSystemProperties(instance, systemId, ref properties);
delegate int xrCreateFacialTrackerHTCDelegate(ulong session, XrFacialTrackerCreateInfoHTC createInfo, out ulong expression);
xrCreateFacialTrackerHTCDelegate m_xrCreateFacialTrackerHTC;
public int xrCreateFacialTrackerHTC(XrFacialTrackerCreateInfoHTC createInfo ,out ulong handle) =>
m_xrCreateFacialTrackerHTC(m_XrSession, createInfo, out handle);
public int xrCreateFacialTrackerHTC(ulong session, XrFacialTrackerCreateInfoHTC createInfo, out ulong handle) =>
m_xrCreateFacialTrackerHTC(session, createInfo, out handle);
delegate int xrDestroyFacialTrackerHTCDelegate(ulong facialTracker);
xrDestroyFacialTrackerHTCDelegate m_xrDestroyFacialTrackerHTC;
public int xrDestroyFacialTrackerHTC(ulong handle) =>
m_xrDestroyFacialTrackerHTC(handle);
delegate int xrGetFacialExpressionsHTCDelegate(ulong facialTracker, ref XrFacialExpressionsHTC eyeExpressionData);
xrGetFacialExpressionsHTCDelegate m_xrGetFacialExpressionsHTC;
public int xrGetFacialExpressionsHTC(ulong handle,ref XrFacialExpressionsHTC eyeExpressionData) =>
m_xrGetFacialExpressionsHTC(handle, ref eyeExpressionData);
public unsafe void SystemSupportsFacialTracking(out XrResult result,out bool isSupportEye,out bool isSupportLip)
{
XrSystemFacialTrackingPropertiesHTC expressionProperties = new XrSystemFacialTrackingPropertiesHTC
{
type = XrStructureType.XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC,
next = IntPtr.Zero,
};
var systemProp = new XrSystemProperties()
{
type = XrStructureType.XR_TYPE_SYSTEM_PROPERTIES,
next = (IntPtr)(&expressionProperties),
};
result = (XrResult)xrGetSystemProperties(XrInstance, SystemId ,ref systemProp);
isSupportEye = expressionProperties.supportEyeFacialTracking != 0;
isSupportLip = expressionProperties.supportLipFacialTracking != 0;
}
public bool TryCreateFacialTracker(XrFacialTrackingTypeHTC type,out ulong handle, out XrResult result)
{
XrFacialTrackerCreateInfoHTC createInfo = new XrFacialTrackerCreateInfoHTC(
XrStructureType.XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC,
IntPtr.Zero,
type);
result = (XrResult)xrCreateFacialTrackerHTC(XrSession,createInfo, out handle);
return result == XrResult.XR_SUCCESS;
}
public bool TryDestroFacialTracker(ulong handle, out XrResult result)
{
result= (XrResult)xrDestroyFacialTrackerHTC(handle);
return result == XrResult.XR_SUCCESS;
}
public bool TryGetFacialData(ulong handle,out bool isActive,int maxExpressioncount,out XrResult result,float[] blendshapes)
{
XrFacialExpressionsHTC facialExpression = new XrFacialExpressionsHTC()
{
type = XrStructureType.XR_TYPE_FACIAL_EXPRESSIONS_HTC,
expressionCount = maxExpressioncount,
sampleTime = 10L, //An arbitrary number greater than 0
blendShapeWeightings = Marshal.AllocCoTaskMem(sizeof(float) * maxExpressioncount),
};
result = (XrResult)xrGetFacialExpressionsHTC(handle, ref facialExpression);
Marshal.Copy(facialExpression.blendShapeWeightings, blendshapes, 0, maxExpressioncount);
isActive = facialExpression.isActive != 0u;
return result == XrResult.XR_SUCCESS;
}
}
}
}

View File

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

View File

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

View File

@@ -1,681 +0,0 @@
using System.Collections.Generic;
using UnityEngine.InputSystem.XR;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Scripting;
using UnityEngine.XR.OpenXR.Features.Interactions;
using UnityEngine.XR.OpenXR.Input;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if USE_INPUT_SYSTEM_POSE_CONTROL
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
#else
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
#endif
namespace UnityEngine.XR.OpenXR.Features
{
/// <summary>
/// This <see cref="OpenXRInteractionFeature"/> enables the use of HTC Vive Focus3 Controllers interaction profiles in OpenXR.
/// </summary>
#if UNITY_EDITOR
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "HTC Vive Focus3 Controller Support",
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA },
Company = "HTC",
Desc = "Allows for mapping input to the HTC Vive Focus3 Controller interaction profile.",
//DocumentationLink = "https://developer.vive.com/resources/openxr/openxr-pcvr/tutorials/unity/cosmos-controller-openxr-feature-unity/",
OpenxrExtensionStrings = "XR_HTC_vive_focus3_controller_interaction XR_EXT_palm_pose",
Version = "0.0.2",
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
FeatureId = featureId)]
#endif
public class HtcViveFocus3InputFeature : OpenXRInteractionFeature
{
/// <summary>
/// The feature id string. This is used to give the feature a well known id for reference.
/// </summary>
public const string featureId = "com.htc.openxr.feature.input.htcvivefocus3";
/// <summary>
/// An Input System device based off the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_vive_focus3_controller_interaction">HTC Vive Controller</see>.
/// </summary>
///
[Preserve, InputControlLayout(displayName = "HTC Vive Focus3 Controller (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
public class ViveFocus3Controller : XRControllerWithRumble
{
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.thumbrestTouched"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "thumbresttouch" })]
public ButtonControl thumbrestTouched { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.squeezeTouched"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "griptouch" })]
public ButtonControl gripTouched { get; private set; }
/// <summary>
/// A <see cref="AxisControl"/> representing information from the <see cref="HtcViveFocus3Controller.squeeze"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "GripAxis" })]
public AxisControl grip { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.squeezeClick"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "GripButton" })]
public ButtonControl gripPressed { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing the <see cref="HtcViveFocus3Controller.b"/> <see cref="HtcViveFocus3Controller.y"/> OpenXR bindings, depending on handedness.
/// </summary>
[Preserve, InputControl(aliases = new[] { "B", "Y" })]
public ButtonControl secondaryButton { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing the <see cref="HtcViveFocus3Controller.a"/> <see cref="HtcViveFocus3Controller.x"/> OpenXR bindings, depending on handedness.
/// </summary>
[Preserve, InputControl(aliases = new[] { "A", "X" })]
public ButtonControl primaryButton { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.menu"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "Primary", "menubutton" })]
public ButtonControl menu { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.triggerTouch"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "triggertouch" })]
public ButtonControl triggerTouched { get; private set; }
/// <summary>
/// A <see cref="AxisControl"/> representing information from the <see cref="HtcViveFocus3Controller.trigger"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "triggeraxis" })]
public AxisControl trigger { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.triggerClick"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "triggerbutton" })]
public ButtonControl triggerPressed { get; private set; }
/// <summary>
/// A <see cref="Vector2Control"/> representing information from the <see cref="HtcViveFocus3Controller.joystick"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "Primary2DAxis", "joystickaxes" })]
public Vector2Control joystick { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.joystickClick"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "joystickorpadpressed", "joystickpressed" })]
public ButtonControl joystickClicked { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> representing information from the <see cref="HtcViveFocus3Controller.joystickTouched"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "joystickorpadtouched", "joysticktouched" })]
public ButtonControl joystickTouched { get; private set; }
/// <summary>
/// A <see cref="PoseControl"/> representing information from the <see cref="HtcViveFocus3Controller.grip"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(offset = 0, alias = "device")]
public PoseControl devicePose { get; private set; }
/// <summary>
/// A <see cref="PoseControl"/> representing information from the <see cref="HtcViveFocus3Controller.aim"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(offset = 0)]
public PoseControl pointer { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> required for back compatibility with the XRSDK layouts. this represents the overall tracking state of the device. this value is equivalent to mapping devicePose/isTracked
/// </summary>
[Preserve, InputControl(offset = 28)]
new public ButtonControl isTracked { get; private set; }
/// <summary>
/// A <see cref="IntegerControl"/> required for back compatibility with the XRSDK layouts. this represents the bit flag set indicating what data is valid. this value is equivalent to mapping devicePose/trackingState
/// </summary>
[Preserve, InputControl(offset = 32)]
new public IntegerControl trackingState { get; private set; }
/// <summary>
/// A <see cref="Vector3Control"/> required for back compatibility with the XRSDK layouts. this is the device position, or grip position. this value is equivalent to mapping devicePose/position
/// </summary>
[Preserve, InputControl(offset = 36, aliases = new[] { "gripPosition" })]
new public Vector3Control devicePosition { get; private set; }
/// <summary>
/// A <see cref="QuaternionControl"/> required for back compatibility with the XRSDK layouts. this is the device orientation, or grip orientation. this value is equivalent to mapping devicePose/rotation
/// </summary>
[Preserve, InputControl(offset = 48, aliases = new[] { "gripOrientation", "gripRotation" })]
new public QuaternionControl deviceRotation { get; private set; }
/// A <see cref="Vector3Control"/> required for back compatibility with the XRSDK layouts. this is the pointer position. this value is equivalent to mapping pointerPose/position
/// </summary>
[Preserve, InputControl(offset = 96)]
public Vector3Control pointerPosition { get; private set; }
/// <summary>
/// A <see cref="QuaternionControl"/> required for back compatibility with the XRSDK layouts. this is the pointer rotation. this value is equivalent to mapping pointerPose/rotation
/// </summary>
[Preserve, InputControl(offset = 108, aliases = new[] { "pointerOrientation" })]
public QuaternionControl pointerRotation { get; private set; }
/// <summary>
/// A <see cref="HapticControl"/> that represents the <see cref="HtcViveFocus3Controller.haptic"/> binding.
/// </summary>
[Preserve, InputControl(usage = "Haptic")]
public HapticControl haptic { get; private set; }
/// <summary>
/// A <see cref="PoseControl"/> representing information from the <see cref="HtcViveFocus3Controller.palm"/> OpenXR binding.
/// </summary>
[Preserve, InputControl()]
public PoseControl palm { get; private set; }
protected override void FinishSetup()
{
base.FinishSetup();
thumbrestTouched = GetChildControl<ButtonControl>("thumbrestTouched");
gripTouched = GetChildControl<ButtonControl>("gripTouched");
grip = GetChildControl<AxisControl>("grip");
gripPressed = GetChildControl<ButtonControl>("gripPressed");
primaryButton = GetChildControl<ButtonControl>("primaryButton");
secondaryButton = GetChildControl<ButtonControl>("secondaryButton");
menu = GetChildControl<ButtonControl>("menu");
trigger = GetChildControl<AxisControl>("trigger");
triggerTouched = GetChildControl<ButtonControl>("triggerTouched");
triggerPressed = GetChildControl<ButtonControl>("triggerPressed");
joystick = GetChildControl<Vector2Control>("joystick");
joystickClicked = GetChildControl<ButtonControl>("joystickClicked");
joystickTouched = GetChildControl<ButtonControl>("joystickTouched");
devicePose = GetChildControl<PoseControl>("devicePose");
pointer = GetChildControl<PoseControl>("pointer");
isTracked = GetChildControl<ButtonControl>("isTracked");
trackingState = GetChildControl<IntegerControl>("trackingState");
devicePosition = GetChildControl<Vector3Control>("devicePosition");
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
haptic = GetChildControl<HapticControl>("haptic");
palm = GetChildControl<PoseControl>("palm");
}
}
/// <summary>The interaction profile string used to reference the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_vive_focus3_controller_interaction">HTC Vive Focus3 Controller</see>.</summary>
public const string profile = "/interaction_profiles/htc/vive_focus3_controller";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/trigger/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string select = "/input/trigger/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/a/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string a = "/input/a/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/b/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string b = "/input/b/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/x/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string x = "/input/x/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/y/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string y = "/input/y/click";
/// <summary>
/// Constant for a <see cref="ActionType.Axis1D"/> interaction binding '.../input/squeeze/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string squeeze = "/input/squeeze/value";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/squeeze/touch' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string squeezeTouch = "/input/squeeze/touch";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/squeeze/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string squeezeClick = "/input/squeeze/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/menu/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string menu = "/input/menu/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/trigger/touch' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string triggerTouch = "/input/trigger/touch";
/// <summary>
/// Constant for a <see cref="ActionType.Axis1D"/> interaction binding '.../input/trigger/value' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string trigger = "/input/trigger/value";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/trigger/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string triggerClick = "/input/trigger/click";
/// <summary>
/// Constant for a <see cref="ActionType.Axis2D"/> interaction binding '.../input/trackpad' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string thumbstick = "/input/thumbstick";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/trackpad/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string thumbstickClick = "/input/thumbstick/click";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/trackpad/touch' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string thumbstickTouch = "/input/thumbstick/touch";
/// <summary>
/// Constant for a <see cref="ActionType.Pose"/> interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string grip = "/input/grip/pose";
/// <summary>
/// Constant for a <see cref="ActionType.Pose"/> interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string aim = "/input/aim/pose";
/// <summary>
/// Constant for a <see cref="ActionType.Vibrate"/> interaction binding '.../output/haptic' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string haptic = "/output/haptic";
/// <summary>
/// Constant for a <see cref="ActionType.Pose"/> interaction binding '.../input/palm_ext/pose' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string palm = "/input/palm_ext/pose";
/// <summary>
/// Constant for a <see cref="ActionType.Binary"/> interaction binding '.../input/thumbrest/touch' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string thumbrest = "/input/thumbrest/touch";
private const string kDeviceLocalizedName = "HTC Vive Focus3 Controller OpenXR";
/// <summary>
/// Registers the <see cref="ViveFocus3Controller"/> layout with the Input System. Matches the <see cref="ActionMapConfig"/> that is registered with <see cref="RegisterControllerMap"/>.
/// </summary>
protected override void RegisterDeviceLayout()
{
InputSystem.InputSystem.RegisterLayout(typeof(ViveFocus3Controller),
matches: new InputDeviceMatcher()
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
.WithProduct(kDeviceLocalizedName));
}
/// <summary>
/// Removes the <see cref="ViveFocus3Controller"/> layout from the Input System. Matches the <see cref="ActionMapConfig"/> that is registered with <see cref="RegisterControllerMap"/>.
/// </summary>
protected override void UnregisterDeviceLayout()
{
InputSystem.InputSystem.RemoveLayout(typeof(ViveFocus3Controller).Name);
}
/// <summary>
/// Registers an <see cref="ActionMapConfig"/> with OpenXR that matches the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_vive_focus3_controller_interaction">HTC Vive Focus3 Controller</see>. Also calls <see cref="RegisterDeviceLayout"/> when the Input System package is available.
/// </summary>
protected override void RegisterActionMapsWithRuntime()
{
ActionMapConfig actionMap = new ActionMapConfig()
{
name = "vivefocus3controller",
localizedName = kDeviceLocalizedName,
desiredInteractionProfile = profile,
manufacturer = "HTC",
serialNumber = "",
deviceInfos = new List<DeviceConfig>()
{
new DeviceConfig()
{
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Left),
userPath = UserPaths.leftHand
},
new DeviceConfig()
{
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.Right),
userPath = UserPaths.rightHand
}
},
actions = new List<ActionConfig>()
{
new ActionConfig()
{
name = "primarybutton",
localizedName = "Primary Button",
type = ActionType.Binary,
usages = new List<string>()
{
"PrimaryButton"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = x,
interactionProfileName = profile,
userPaths = new List<string>() { UserPaths.leftHand }
},
new ActionBinding()
{
interactionPath = a,
interactionProfileName = profile,
userPaths = new List<string>() { UserPaths.rightHand }
},
}
},
new ActionConfig()
{
name = "secondarybutton",
localizedName = "Secondary Button",
type = ActionType.Binary,
usages = new List<string>()
{
"SecondaryButton"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = y,
interactionProfileName = profile,
userPaths = new List<string>() { UserPaths.leftHand }
},
new ActionBinding()
{
interactionPath = b,
interactionProfileName = profile,
userPaths = new List<string>() { UserPaths.rightHand }
},
}
},
new ActionConfig()
{
name = "thumbrestTouched",
localizedName = "Thumbrest Touched",
type = ActionType.Binary,
usages = new List<string>()
{
"ThumbrestTouch",
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = thumbrest,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "grip",
localizedName = "Grip",
type = ActionType.Axis1D,
usages = new List<string>()
{
"Grip"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = squeeze,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "gripTouched",
localizedName = "Grip Touched",
type = ActionType.Binary,
usages = new List<string>()
{
"GripTouch",
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = squeezeTouch,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "grippressed",
localizedName = "Grip Pressed",
type = ActionType.Binary,
usages = new List<string>()
{
"GripPressed",
"GripButton"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = squeezeClick,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "menu",
localizedName = "Menu",
type = ActionType.Binary,
usages = new List<string>()
{
"MenuButton"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = menu,
interactionProfileName = profile,
userPaths = new List<string>() { UserPaths.leftHand }
}
}
},
new ActionConfig()
{
name = "trigger",
localizedName = "Trigger",
type = ActionType.Axis1D,
usages = new List<string>()
{
"Trigger"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = trigger,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "triggerTouched",
localizedName = "TriggerTouched",
type = ActionType.Binary,
usages = new List<string>()
{
"TriggerTouch"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = triggerTouch,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "triggerpressed",
localizedName = "Trigger Pressed",
type = ActionType.Binary,
usages = new List<string>()
{
"TriggerPressed",
"TriggerButton"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = triggerClick,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "thumbstick",
localizedName = "Thumbstick",
type = ActionType.Axis2D,
usages = new List<string>()
{
"Primary2DAxis"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = thumbstick,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "thumbsticktouched",
localizedName = "Thumbstick Touched",
type = ActionType.Binary,
usages = new List<string>()
{
"Primary2DAxisTouch"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = thumbstickTouch,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "thumbstickclicked",
localizedName = "Thumbstick Clicked",
type = ActionType.Binary,
usages = new List<string>()
{
"Primary2DAxisClick"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = thumbstickClick,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "devicepose",
localizedName = "Device Pose",
type = ActionType.Pose,
usages = new List<string>()
{
"Device"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = grip,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "pointer",
localizedName = "Pointer Pose",
type = ActionType.Pose,
usages = new List<string>()
{
"Pointer"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = aim,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "haptic",
localizedName = "Haptic Output",
type = ActionType.Vibrate,
usages = new List<string>() { "Haptic" },
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = haptic,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "palm",
localizedName = "Palm Pose",
type = ActionType.Pose,
usages = new List<string>()
{
"Palm"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = palm,
interactionProfileName = profile,
}
}
}
}
};
AddActionMap(actionMap);
}
}
}

View File

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

View File

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

View File

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

View File

@@ -1,268 +0,0 @@
using System.Collections.Generic;
using UnityEngine.InputSystem.XR;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Scripting;
using UnityEngine.XR.OpenXR.Features.Interactions;
using UnityEngine.XR.OpenXR.Input;
#if UNITY_EDITOR
using UnityEditor;
#endif
#if USE_INPUT_SYSTEM_POSE_CONTROL
using PoseControl = UnityEngine.InputSystem.XR.PoseControl;
#else
using PoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
#endif
namespace UnityEngine.XR.OpenXR.Features
{
/// <summary>
/// This <see cref="OpenXRInteractionFeature"/> enables the use of HTC Vive hand interaction profiles in OpenXR.
/// </summary>
#if UNITY_EDITOR
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "HTC Vive hand interaction Support",
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA },
Company = "HTC",
Desc = "Allows for mapping input to the HTC Vive hand interaction interaction profile.",
DocumentationLink = "https://developer.vive.com/resources/openxr/openxr-pcvr/tutorials/unity/hand-interaction-profile/",
OpenxrExtensionStrings = "XR_HTC_hand_interaction",
Version = "0.0.1",
Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction,
FeatureId = featureId)]
#endif
public class HtcViveHandInteractionInputFeature : OpenXRInteractionFeature
{
/// <summary>
/// The feature id string. This is used to give the feature a well known id for reference.
/// </summary>
public const string featureId = "com.htc.openxr.feature.input.htcvivehandinteraction";
/// <summary>
/// An Input System device based off the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_hand_interaction">HTC Vive Controller</see>.
/// </summary>
///
[Preserve, InputControlLayout(displayName = "HTC Vive hand interaction (OpenXR)", commonUsages = new[] { "LeftHand", "RightHand" })]
public class ViveHandInteraction : XRController
{
/// <summary>
/// A <see cref="AxisControl"/> representing information from the <see cref="HtcViveHandInteraction.squeeze"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "GripAxis" })]
public AxisControl grip { get; private set; }
/// <summary>
/// A <see cref="AxisControl"/> representing information from the <see cref="HtcViveHandInteraction.select"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(aliases = new[] { "selectaxis" })]
public AxisControl select { get; private set; }
/// <summary>
/// A <see cref="PoseControl"/> representing information from the <see cref="HtcViveHandInteraction.grip"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(offset = 0, alias = "device")]
public PoseControl devicePose { get; private set; }
/// <summary>
/// A <see cref="PoseControl"/> representing information from the <see cref="HtcViveHandInteraction.aim"/> OpenXR binding.
/// </summary>
[Preserve, InputControl(offset = 0)]
public PoseControl pointer { get; private set; }
/// <summary>
/// A <see cref="ButtonControl"/> required for back compatibility with the XRSDK layouts. this represents the overall tracking state of the device. this value is equivalent to mapping devicePose/isTracked
/// </summary>
[Preserve, InputControl(offset = 28)]
new public ButtonControl isTracked { get; private set; }
/// <summary>
/// A <see cref="IntegerControl"/> required for back compatibility with the XRSDK layouts. this represents the bit flag set indicating what data is valid. this value is equivalent to mapping devicePose/trackingState
/// </summary>
[Preserve, InputControl(offset = 32)]
new public IntegerControl trackingState { get; private set; }
/// <summary>
/// A <see cref="Vector3Control"/> required for back compatibility with the XRSDK layouts. this is the device position, or grip position. this value is equivalent to mapping devicePose/position
/// </summary>
[Preserve, InputControl(offset = 36, aliases = new[] { "gripPosition" })]
new public Vector3Control devicePosition { get; private set; }
/// <summary>
/// A <see cref="QuaternionControl"/> required for back compatibility with the XRSDK layouts. this is the device orientation, or grip orientation. this value is equivalent to mapping devicePose/rotation
/// </summary>
[Preserve, InputControl(offset = 48, aliases = new[] { "gripOrientation", "gripRotation" })]
new public QuaternionControl deviceRotation { get; private set; }
/// A <see cref="Vector3Control"/> required for back compatibility with the XRSDK layouts. this is the pointer position. this value is equivalent to mapping pointerPose/position
/// </summary>
[Preserve, InputControl(offset = 96)]
public Vector3Control pointerPosition { get; private set; }
/// <summary>
/// A <see cref="QuaternionControl"/> required for back compatibility with the XRSDK layouts. this is the pointer rotation. this value is equivalent to mapping pointerPose/rotation
/// </summary>
[Preserve, InputControl(offset = 108, aliases = new[] { "pointerOrientation" })]
public QuaternionControl pointerRotation { get; private set; }
protected override void FinishSetup()
{
base.FinishSetup();
grip = GetChildControl<AxisControl>("grip");
select = GetChildControl<AxisControl>("select");
devicePose = GetChildControl<PoseControl>("devicePose");
pointer = GetChildControl<PoseControl>("pointer");
isTracked = GetChildControl<ButtonControl>("isTracked");
trackingState = GetChildControl<IntegerControl>("trackingState");
devicePosition = GetChildControl<Vector3Control>("devicePosition");
deviceRotation = GetChildControl<QuaternionControl>("deviceRotation");
pointerPosition = GetChildControl<Vector3Control>("pointerPosition");
pointerRotation = GetChildControl<QuaternionControl>("pointerRotation");
}
}
/// <summary>The interaction profile string used to reference the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_hand_interaction">HTC Vive hand interaction</see>.</summary>
public const string profile = "/interaction_profiles/htc/hand_interaction";
/// <summary>
/// Constant for a <see cref="ActionType.Axis1D"/> interaction binding '.../input/squeeze/click' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string squeeze = "/input/squeeze/value";
/// <summary>
/// Constant for a <see cref="ActionType.Axis1D"/> interaction binding '.../input/select/value' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string select = "/input/select/value";
/// <summary>
/// Constant for a <see cref="ActionType.Pose"/> interaction binding '.../input/grip/pose' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string grip = "/input/grip/pose";
/// <summary>
/// Constant for a <see cref="ActionType.Pose"/> interaction binding '.../input/aim/pose' OpenXR Input Binding. Used by <see cref="XrActionConfig"/> to bind actions to physical inputs.
/// </summary>
public const string aim = "/input/aim/pose";
private const string kDeviceLocalizedName = "HTC Vive hand interaction OpenXR";
/// <summary>
/// Registers the <see cref="ViveHandInteraction"/> layout with the Input System. Matches the <see cref="ActionMapConfig"/> that is registered with <see cref="RegisterControllerMap"/>.
/// </summary>
protected override void RegisterDeviceLayout()
{
InputSystem.InputSystem.RegisterLayout(typeof(ViveHandInteraction),
matches: new InputDeviceMatcher()
.WithInterface(XRUtilities.InterfaceMatchAnyVersion)
.WithProduct(kDeviceLocalizedName));
}
/// <summary>
/// Removes the <see cref="ViveHandInteraction"/> layout from the Input System. Matches the <see cref="ActionMapConfig"/> that is registered with <see cref="RegisterControllerMap"/>.
/// </summary>
protected override void UnregisterDeviceLayout()
{
InputSystem.InputSystem.RemoveLayout(typeof(ViveHandInteraction).Name);
}
/// <summary>
/// Registers an <see cref="ActionMapConfig"/> with OpenXR that matches the <see cref="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_hand_interaction">HTC Vive hand interaction</see>. Also calls <see cref="RegisterDeviceLayout"/> when the Input System package is available.
/// </summary>
protected override void RegisterActionMapsWithRuntime()
{
ActionMapConfig actionMap = new ActionMapConfig()
{
name = "ViveHandInteraction",
localizedName = kDeviceLocalizedName,
desiredInteractionProfile = profile,
manufacturer = "HTC",
serialNumber = "",
deviceInfos = new List<DeviceConfig>()
{
new DeviceConfig()
{
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.Left),
userPath = "/user/hand_htc/left"
},
new DeviceConfig()
{
characteristics = (InputDeviceCharacteristics)(InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.HandTracking | InputDeviceCharacteristics.Right),
userPath = "/user/hand_htc/right"
}
},
actions = new List<ActionConfig>()
{
new ActionConfig()
{
name = "grip",
localizedName = "Grip",
type = ActionType.Axis1D,
usages = new List<string>()
{
"Grip"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = squeeze,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "select",
localizedName = "Select",
type = ActionType.Axis1D,
usages = new List<string>()
{
"Select"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = select,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "devicepose",
localizedName = "Device Pose",
type = ActionType.Pose,
usages = new List<string>()
{
"Device"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = grip,
interactionProfileName = profile,
}
}
},
new ActionConfig()
{
name = "pointer",
localizedName = "Pointer Pose",
type = ActionType.Pose,
usages = new List<string>()
{
"Pointer"
},
bindings = new List<ActionBinding>()
{
new ActionBinding()
{
interactionPath = aim,
interactionProfileName = profile,
}
}
}
}
};
AddActionMap(actionMap);
}
}
}

View File

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

View File

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

View File

@@ -1,54 +0,0 @@
using UnityEditor;
using UnityEditor.XR.OpenXR.Features;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using System;
using System.Linq;
using System.Reflection;
using System.IO;
using VIVE.HandTracking;
using UnityEngine.XR.OpenXR.Features;
namespace UnityEditor.XR.OpenXR.Samples.HandTracking
{
[InitializeOnLoad]
public class HandTrackingFeauterInstaller : Editor
{
#if !UNITY_SAMPLE_DEV
private const string k_ScriptPath = "HandTracking Example/Editor/HandTrackingFeauterInstaller.cs";
static HandTrackingFeauterInstaller()
{
FeatureHelpers.RefreshFeatures(BuildTargetGroup.Standalone);
var feature = OpenXRSettings.Instance.GetFeature<HandTracking_OpenXR_API>();
var HandInteractionfeature = OpenXRSettings.Instance.GetFeature<HtcViveHandInteractionInputFeature>();
if (feature != null)
{
if (feature.enabled != true)
{
feature.enabled = true;
}
}
if (HandInteractionfeature != null)
{
if (HandInteractionfeature.enabled != true)
{
HandInteractionfeature.enabled = true;
}
}
Debug.Log(AssetDatabase.FindAssets(Path.GetFileNameWithoutExtension(k_ScriptPath)).Select(AssetDatabase.GUIDToAssetPath));
var source = AssetDatabase.FindAssets(Path.GetFileNameWithoutExtension(k_ScriptPath))
.Select(AssetDatabase.GUIDToAssetPath)
.FirstOrDefault(r => r.Contains(k_ScriptPath));
if (string.IsNullOrEmpty(source))
{
Debug.LogError("File Not Exist");
return;
}
source = Path.GetDirectoryName(source);
Debug.Log(source);
AssetDatabase.DeleteAsset(Path.Combine(Path.GetDirectoryName(source), "Editor"));
}
#endif
}
}

View File

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

View File

@@ -1,182 +0,0 @@
{
"name": "HandInteractions",
"maps": [
{
"name": "LeftHand",
"id": "9ef2cbaf-c5ca-4f94-afd3-c13e92ae39b0",
"actions": [
{
"name": "select",
"type": "Value",
"id": "9f7476ef-5e86-4fbd-be2a-d191fcd6bd90",
"expectedControlType": "Axis",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "grip",
"type": "Value",
"id": "58e87055-a7f7-49e5-874c-ed1531b2fc73",
"expectedControlType": "Axis",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "selectPose",
"type": "Value",
"id": "2427c326-992b-4b5e-8b32-65766a69b9f6",
"expectedControlType": "Pose",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "devicePose",
"type": "Value",
"id": "14167057-a039-4b71-b169-ae012bc4f26b",
"expectedControlType": "Pose",
"processors": "",
"interactions": "",
"initialStateCheck": true
}
],
"bindings": [
{
"name": "",
"id": "b403b14a-c930-45f9-9a3e-2710e4721344",
"path": "<ViveHandInteraction>{LeftHand}/select",
"interactions": "",
"processors": "",
"groups": "",
"action": "select",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "ae0a8fd0-79a3-4996-8334-0c00727c214a",
"path": "<ViveHandInteraction>{LeftHand}/grip",
"interactions": "",
"processors": "",
"groups": "",
"action": "grip",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "86a6d936-0c97-411d-81bd-f07526f0fd2d",
"path": "<ViveHandInteraction>{LeftHand}/pointer",
"interactions": "",
"processors": "",
"groups": "",
"action": "selectPose",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "fc0059b7-df77-4d61-9aff-2ca9cd129ca0",
"path": "<ViveHandInteraction>{LeftHand}/devicePose",
"interactions": "",
"processors": "",
"groups": "",
"action": "devicePose",
"isComposite": false,
"isPartOfComposite": false
}
]
},
{
"name": "RightHand",
"id": "052ff2d7-a697-4084-a818-72ef080c524d",
"actions": [
{
"name": "select",
"type": "Value",
"id": "9939050e-1af5-43fd-815b-92041d19b3fa",
"expectedControlType": "Axis",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "grip",
"type": "Value",
"id": "de49cd41-9a9a-429c-9130-f794cb429550",
"expectedControlType": "Axis",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "selectPose",
"type": "Value",
"id": "60fe8382-aa5a-4fd9-80cf-6ecc68f90863",
"expectedControlType": "Pose",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "devicePose",
"type": "Value",
"id": "192485c2-2d24-495b-8deb-14f2e327a887",
"expectedControlType": "Pose",
"processors": "",
"interactions": "",
"initialStateCheck": true
}
],
"bindings": [
{
"name": "",
"id": "9ff68142-4e5e-4d24-aed3-a377c8b74534",
"path": "<ViveHandInteraction>{RightHand}/select",
"interactions": "",
"processors": "",
"groups": "",
"action": "select",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "23ee2cda-2db6-4e45-b13a-259aabd637f1",
"path": "<ViveHandInteraction>{RightHand}/grip",
"interactions": "",
"processors": "",
"groups": "",
"action": "grip",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "34315523-7e62-43c9-84fc-35cea4259fe5",
"path": "<ViveHandInteraction>{RightHand}/pointer",
"interactions": "",
"processors": "",
"groups": "",
"action": "selectPose",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "4070b955-5c40-46fa-98c5-4c71f99cb6c6",
"path": "<ViveHandInteraction>{RightHand}/devicePose",
"interactions": "",
"processors": "",
"groups": "",
"action": "devicePose",
"isComposite": false,
"isPartOfComposite": false
}
]
}
],
"controlSchemes": []
}

View File

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

View File

@@ -1,541 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &7423157989283898626
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7423157989283898627}
m_Layer: 0
m_Name: 3DHand
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7423157989283898627
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7423157989283898626}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.015607998, y: -0.013282664, z: -0.07335153}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 6957748758881164380}
- {fileID: 6957748757999106292}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &7423157989289999287
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 7423157989283898627}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_RootOrder
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalPosition.x
value: 0.015607998
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalPosition.y
value: 0.013282664
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalPosition.z
value: 0.07335153
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -1107956732406458091, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 9513f1085c3b8d84ab17245d74043608, type: 2}
- target: {fileID: 919132149155446097, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_Name
value: ObjModelHandLeft_26
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
--- !u!4 &1023837832511550131 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -1643464455024064252, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1517851468531354918 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8220238113505965713, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1587043492754875532 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8143094687746776891, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1822319482427487084 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 9101342973431810267, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2129234081217865112 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8829542094526668335, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2402645123296224636 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 5067591772060704459, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2591330329871673071 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4968064022332693848, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2877863616158530621 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4680475222046787466, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &3886056980242657624 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -3248688629254337809, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &3923137174990642617 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 5869758926971069966, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4176209744140450023 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6841172885717877584, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4227981583638641158 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -2474565242041466447, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4315334464559039638 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6694459045059854113, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4518116779036985979 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6464857450473386444, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4655153904485345964 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -6368592266354454245, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5633725182928596562 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2966563632883308005, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5751558732041407126 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2942538225671237921, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5847509038455621992 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 3900922814075712223, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &6366441487635361211 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -4657146349703457268, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!1 &6673696290973803778 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 4294711893310725813, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &6957748758881164380 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7007883643249497524 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8771503716632908285, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7113238653529847310 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 410696192037670329, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7125949936140118471 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 423390500807168624, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7402668014366828115 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -9097317933092135452, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!1 &7765669265330833126 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!114 &7423157989402685039
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7765669265330833126}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c19189c6a6028a74ab475048ebd154c8, type: 3}
m_Name:
m_EditorClassIdentifier:
nodes:
- {fileID: 5847509038455621992}
- {fileID: 1517851468531354918}
- {fileID: 4227981583638641158}
- {fileID: 2591330329871673071}
- {fileID: 7007883643249497524}
- {fileID: 2129234081217865112}
- {fileID: 9190276837785830995}
- {fileID: 4518116779036985979}
- {fileID: 8951308887720329310}
- {fileID: 7113238653529847310}
- {fileID: 7402668014366828115}
- {fileID: 4655153904485345964}
- {fileID: 7929466683079983724}
- {fileID: 4176209744140450023}
- {fileID: 5751558732041407126}
- {fileID: 1822319482427487084}
- {fileID: 6366441487635361211}
- {fileID: 2877863616158530621}
- {fileID: 3886056980242657624}
- {fileID: 1023837832511550131}
- {fileID: 4315334464559039638}
- {fileID: 3923137174990642617}
- {fileID: 7125949936140118471}
- {fileID: 5633725182928596562}
- {fileID: 2402645123296224636}
- {fileID: 1587043492754875532}
isLeft: 1
allowUntrackedPose: 1
Hand: {fileID: 6673696290973803778}
MotionType: 2147483647
--- !u!4 &7929466683079983724 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8570555479703635493, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &8951308887720329310 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -7260599894360605719, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!4 &9190276837785830995 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -7453960083844481564, guid: 9a01667fc6435cb479a0445610133fcc, type: 3}
m_PrefabInstance: {fileID: 7423157989289999287}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &7423157990146891551
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 7423157989283898627}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalPosition.x
value: 0.015607998
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalPosition.y
value: 0.013282664
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalPosition.z
value: 0.07335153
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_Name
value: ObjModelHandRight_26
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7227333814368855109, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 9513f1085c3b8d84ab17245d74043608, type: 2}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
--- !u!4 &1023837833795835419 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -1643464455024064252, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1517851467915504014 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8220238113505965713, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1587043491765714980 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8143094687746776891, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &1822319483682314180 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 9101342973431810267, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2129234081841414448 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8829542094526668335, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2402645124683137492 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 5067591772060704459, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2591330330460226119 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4968064022332693848, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &2877863616882874517 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 4680475222046787466, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &3886056978715186672 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -3248688629254337809, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &3923137175738595601 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 5869758926971069966, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4176209743526845519 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6841172885717877584, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4227981582215536302 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -2474565242041466447, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4315334463274852414 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6694459045059854113, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4518116778316803795 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 6464857450473386444, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &4655153903869513220 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -6368592266354454245, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!1 &5402561904108644855 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 3313976086554670824, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5633725184492227322 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2966563632883308005, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5751558732801289790 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 2942538225671237921, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &5847509039486725568 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 3900922814075712223, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &6366441486206486803 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -4657146349703457268, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &6957748757999106292 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7007883642229584156 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8771503716632908285, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7113238654822912678 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 410696192037670329, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7125949935415725423 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 423390500807168624, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &7402668015651537659 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -9097317933092135452, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!1 &7765669264174080590 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!114 &7423157990786583661
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7765669264174080590}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c19189c6a6028a74ab475048ebd154c8, type: 3}
m_Name:
m_EditorClassIdentifier:
nodes:
- {fileID: 5847509039486725568}
- {fileID: 1517851467915504014}
- {fileID: 4227981582215536302}
- {fileID: 2591330330460226119}
- {fileID: 7007883642229584156}
- {fileID: 2129234081841414448}
- {fileID: 9190276836226818811}
- {fileID: 4518116778316803795}
- {fileID: 8951308886156731638}
- {fileID: 7113238654822912678}
- {fileID: 7402668015651537659}
- {fileID: 4655153903869513220}
- {fileID: 7929466684471142084}
- {fileID: 4176209743526845519}
- {fileID: 5751558732801289790}
- {fileID: 1822319483682314180}
- {fileID: 6366441486206486803}
- {fileID: 2877863616882874517}
- {fileID: 3886056978715186672}
- {fileID: 1023837833795835419}
- {fileID: 4315334463274852414}
- {fileID: 3923137175738595601}
- {fileID: 7125949935415725423}
- {fileID: 5633725184492227322}
- {fileID: 2402645124683137492}
- {fileID: 1587043491765714980}
isLeft: 0
allowUntrackedPose: 1
Hand: {fileID: 5402561904108644855}
MotionType: 2147483647
--- !u!4 &7929466684471142084 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8570555479703635493, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &8951308886156731638 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -7260599894360605719, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}
--- !u!4 &9190276836226818811 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -7453960083844481564, guid: afa96e79b5b79984ab74e9e1ef200d57, type: 3}
m_PrefabInstance: {fileID: 7423157990146891551}
m_PrefabAsset: {fileID: 0}

View File

@@ -1,26 +0,0 @@
# VIVE OpenXR Hand Tracking Unity Feature
To help software developers create an application for locating hand joints with the OpenXR hand tracking extension [XR_EXT_hand_tracking](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hand_tracking).
## Load sample code
**Window** > **Package Manager** > **VIVE OpenXR Plugin - Windows** > **Samples** > Click to import **HandTracking Example**
## Play the sample scene
1. **Edit** > **Project Settings** > **XR Plug-in Management** > Select **OpenXR** , click Exclamation mark next to it then choose **Fix All**.
2. **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR** > Add Interaction profiles for your device.
3. **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR** > Select **Hand Tracking** under **VIVE OpenXR** Feature Groups.
4. In the Unity Project window, select the sample scene file in **Assets** > **Samples** > **VIVE OpenXR Plugin - Windows** > **1.0.13** > **HandTracking Example** > **Scenes** > **HandTrackingScene.unity** then click Play.
## Use VIVE OpenXR Hand Tracking Unity Feature to draw skeleton hand.
1. Import VIVE OpenXR Plugin - Windows
2. Add Hand gameobject to the Unity scene
- Refer to functions **StartFrameWork** and **StopFrameWork** in **HandManager.cs** for creating and releasing handle for hand.
- Refer to the function **GetJointLocation** in **HandManager.cs** for getting the information to locate hand joints.
- Drag "SkeletonHand" prefab into scene hierarchy or Create an empty object and attach **RenderHand.cs**.
## Use VIVE OpenXR Hand Tracking Unity Feature to draw 3D hand.
1. Import VIVE OpenXR Plugin - Windows
2. Add Hand gameobject to the Unity scene
- Refer to functions **StartFrameWork** and **StopFrameWork** in **HandManager.cs** for creating and releasing handle for hand.
- Refer to the function **GetJointLocation** in **HandManager.cs** for getting the information to locate hand joints.
- Drag "3DHand" prefab into scene hierarchy or attach **RenderModel.cs** to "ObjModelHandLeft_26.fbx" and "ObjModelHandRight_26.fbx".

View File

@@ -1,83 +0,0 @@
using System;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using UnityEngine;
public class Controller : MonoBehaviour
{
[SerializeField]
private InputActionReference m_ActionReferenceTrigger;
public InputActionReference actionReferenceTrigger { get => m_ActionReferenceTrigger ; set => m_ActionReferenceTrigger=value; }
public TextMesh pinchValue;
//[SerializeField]
//private InputActionReference m_ActionReferenceGrip;
//public InputActionReference actionReferenceGrip { get => m_ActionReferenceGrip ; set => m_ActionReferenceGrip=value; }
Type lastActiveType_Trigger = null;
// Update is called once per frame
void Update()
{
pinchValue.text = "0";
if ( actionReferenceTrigger != null && actionReferenceTrigger.action != null
&& actionReferenceTrigger.action.enabled && actionReferenceTrigger.action.controls.Count > 0
/*&& actionReferenceGrip != null && actionReferenceGrip.action != null
&& actionReferenceGrip.action.enabled && actionReferenceGrip.action.controls.Count > 0*/)
{
// Grip
//Type typeToUse_Grip = null;
//if(actionReferenceGrip.action.activeControl != null)
//{
// typeToUse_Grip = actionReferenceGrip.action.activeControl.valueType;
//}
//else
//{
// typeToUse_Grip = lastActiveType_Grip;
//}
//if(typeToUse_Grip == typeof(float))
//{
// lastActiveType_Grip = typeof(float);
// float value = actionReferenceGrip.action.ReadValue<float>();
// if(value > 0.5)
// {
// if(!isSwitchedMeshPrefab)
// {
// isSwitchedMeshPrefab = true;
// Debug.Log("Press Button B.");
// //if(MeshSubSystem != null)
// //{
// // MeshSubSystem.GetComponent<UnityEngine.XR.OpenXR.Samples.MeshingFeature.MeshingBehaviour>().SwitchMeshPrefab();
// //}
// }
// }
// else
// {
// isSwitchedMeshPrefab = false;
// }
//}
// Trigger
Type typeToUse_Trigger = null;
if(actionReferenceTrigger.action.activeControl != null)
{
typeToUse_Trigger = actionReferenceTrigger.action.activeControl.valueType;
}
else
{
typeToUse_Trigger = lastActiveType_Trigger;
}
if(typeToUse_Trigger == typeof(float))
{
lastActiveType_Trigger = typeof(float);
float value = actionReferenceTrigger.action.ReadValue<float>();
pinchValue.text = value.ToString();
}
}
}
}

View File

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

View File

@@ -1,290 +0,0 @@
using System;
using UnityEngine;
using UnityEngine.XR.OpenXR;
using VIVE.HandTracking;
[Obsolete("Use HandManager instead")]
public static class FrameWork
{
private class HandData
{
public bool isStarted;
public XrHandEXT hand;
public ulong trackerHandle;
public bool isActive;
public int jointUpdatedFrame = -1;
public XrHandJointLocationEXT[] joints = new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT];
public XrHandJointVelocityEXT[] velocities = new XrHandJointVelocityEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT];
public bool isCreated { get { return trackerHandle != default; } }
public void ClearJoints()
{
Array.Clear(joints, 0, joints.Length);
Array.Clear(velocities, 0, velocities.Length);
}
}
private static HandTracking_OpenXR_API feature;
private static bool isInitialized;
private static bool isSystemSupported;
private static ulong refSpace;
private static HandData leftHandData = new HandData() { hand = XrHandEXT.XR_HAND_LEFT_EXT };
private static HandData rightHandData = new HandData() { hand = XrHandEXT.XR_HAND_RIGHT_EXT };
private static bool isRefSpaceCreated { get { return refSpace != default; } }
private static HandData GetHandData(bool isLeft)
{
return isLeft ? leftHandData : rightHandData;
}
public static bool Initialize()
{
if (!isInitialized)
{
if (feature == null)
{
feature = OpenXRSettings.Instance.GetFeature<HandTracking_OpenXR_API>();
if (feature != null)
{
// FIXME: Assume featuer instance won't be destroied and created to a new one
feature.onSessionCreate += OnFeatureSessionCreate;
feature.onSessionDestroy += OnFeatureSessionDestroy;
feature.onSystemChange += OnFeatureSystemChange;
}
}
if (feature != null && feature.IsEnabledAndInitialized)
{
UpdateSystemSupported();
isInitialized = true;
}
}
return isInitialized;
}
private static void OnFeatureSessionCreate(ulong xrSession)
{
TryCreateHandTracker(leftHandData);
TryCreateHandTracker(rightHandData);
}
private static void OnFeatureSessionDestroy(ulong xrSession)
{
DestroyHandTracker(leftHandData);
DestroyHandTracker(rightHandData);
DestroyRefSpace();
}
private static void OnFeatureSystemChange(ulong systemId)
{
UpdateSystemSupported();
}
private static void UpdateSystemSupported()
{
if (feature == null || !feature.IsEnabledAndInitialized)
{
isSystemSupported = false;
}
else
{
isSystemSupported = feature.SystemSupportsHandTracking(out var result);
if (!isSystemSupported)
{
if (result != XrResult.XR_SUCCESS)
{
Debug.LogWarning("Fail SystemSupportsHandTracking: " + result);
}
else
{
Debug.LogWarning("Hand tracking not supported by the system");
}
}
}
}
private static bool TryCreateHandTracker(HandData handData)
{
if (!handData.isStarted) { return false; }
if (!Initialize()) { return false; }
if (!isSystemSupported) { return false; }
if (!feature.IsSessionCreated) { return false; }
if (!handData.isCreated)
{
if (!feature.TryCreateHandTracker(handData.hand, out handData.trackerHandle, out var result))
{
handData.trackerHandle = default;
Debug.LogWarning("Fail CreateHandTracker: " + result);
}
}
return handData.isCreated;
}
private static void DestroyHandTracker(HandData handData)
{
if (!handData.isCreated) { return; }
if (!Initialize()) { return; }
feature.TryDestroyHandTracker(handData.trackerHandle, out _);
handData.trackerHandle = default;
handData.ClearJoints();
}
private static bool InitializeRefSpace()
{
if (!Initialize()) { return false; }
if (!isSystemSupported) { return false; }
if (!feature.IsSessionCreated) { return false; }
if (!isRefSpaceCreated)
{
const XrReferenceSpaceType preferSpaceType = XrReferenceSpaceType.XR_REFERENCE_SPACE_TYPE_STAGE;
XrReferenceSpaceType spaceType;
if (!feature.TryGetSupportedReferenceSpaceType(preferSpaceType, out spaceType, out var result))
{
Debug.LogWarning("Fail GetSupportedReferenceSpaceType: " + result);
}
else
{
if (!feature.TryCreateReferenceSpace(
spaceType,
new XrVector3f(0f, 0f, 0f),
new XrQuaternionf(0f, 0f, 0f, 1f),
out refSpace,
out result))
{
refSpace = default;
Debug.LogWarning("Fail CreateReferenceSpace: " + result);
}
}
}
return isRefSpaceCreated;
}
private static void DestroyRefSpace()
{
if (!isRefSpaceCreated) { return; }
if (Initialize())
{
if (!feature.TryDestroyReferenceSpace(refSpace, out var result))
{
Debug.LogWarning("Fail DestroyReferenceSpace: " + result);
}
}
refSpace = default;
}
public static void StartFrameWork(bool isLeft)
{
var handData = GetHandData(isLeft);
handData.isStarted = true;
TryCreateHandTracker(handData);
}
public static void StopFrameWork(bool isLeft)
{
var handData = GetHandData(isLeft);
handData.isStarted = false;
DestroyHandTracker(handData);
}
public static bool GetJointLocation(bool isleft, out XrHandJointLocationEXT[] joints, bool forceUpdate = false)
{
var handData = GetHandData(isleft);
if (handData.isCreated)
{
if (forceUpdate || handData.jointUpdatedFrame != Time.frameCount)
{
handData.jointUpdatedFrame = Time.frameCount;
if (InitializeRefSpace())
{
if (!feature.TryLocateHandJoints(
handData.trackerHandle,
refSpace,
out handData.isActive,
handData.joints,
out var result))
{
handData.isActive = false;
Debug.LogWarning("Fail LocateHandJoints: " + result);
}
}
}
}
joints = handData.joints;
return handData.isActive;
}
public static bool GetJointLocation(bool isleft, out XrHandJointLocationEXT[] joints,ref XrHandJointsMotionRangeEXT type, bool forceUpdate = false)
{
var handData = GetHandData(isleft);
if (handData.isCreated)
{
if (forceUpdate || handData.jointUpdatedFrame != Time.frameCount)
{
handData.jointUpdatedFrame = Time.frameCount;
if (InitializeRefSpace())
{
if (!feature.TryLocateHandJoints(
handData.trackerHandle,
refSpace,
ref type,
out handData.isActive,
handData.joints,
out var result))
{
handData.isActive = false;
Debug.LogWarning("Fail LocateHandJoints: " + result);
}
}
}
}
joints = handData.joints;
return handData.isActive;
}
public static bool GetJointLocation(bool isleft, out XrHandJointLocationEXT[] joints, out XrHandJointVelocityEXT[] velocities, bool forceUpdate = false)
{
var handData = GetHandData(isleft);
if (handData.isCreated)
{
if (forceUpdate || handData.jointUpdatedFrame != Time.frameCount)
{
handData.jointUpdatedFrame = Time.frameCount;
if (InitializeRefSpace())
{
if (!feature.TryLocateHandJoints(
handData.trackerHandle,
refSpace,
out handData.isActive,
handData.joints,
handData.velocities,
out var result))
{
handData.isActive = false;
Debug.LogWarning("Fail LocateHandJoints: " + result);
}
}
}
}
joints = handData.joints;
velocities = handData.velocities;
return handData.isActive;
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More