10 Commits

Author SHA1 Message Date
Sean Lu
2bfa2ad4c7 version 2.5.0 2024-12-06 15:44:37 +08:00
Sean Lu
dfdcd0fd7f version 2.4.2 2024-10-30 16:02:07 +08:00
babelsw_hsu
5ac252bf2e Changed: The License file.
Symptom: Plugin
Root Cause: N/A
Solution: Changed the License file.
Project: VIVE OpenXR Unity Plugin
Note:
2024-09-27 17:49:27 +08:00
Sean
fa1969a087 version 2.4.1 2024-07-18 14:29:33 +08:00
Sean Lu(呂祥榮)
3dd72f5f56 version 2.4.0 2024-07-03 14:58:53 +08:00
Sean Lu(呂祥榮)
7f2a459592 version 2.3.0 2024-05-15 14:09:18 +08:00
srl87
45b4e46f74 version 2.2.0 2024-01-10 14:20:05 +08:00
srl87
11b730e79b update installer 2023-09-14 18:39:28 +08:00
srl87
ca21423a06 version 2.0.0 2023-09-14 18:17:47 +08:00
srl87
13e9d00b37 Update README.md 2023-09-14 17:10:04 +08:00
2101 changed files with 696546 additions and 21216 deletions

Binary file not shown.

4
LICENSE.txt Normal file
View File

@@ -0,0 +1,4 @@
Copyright © HTC Corporation, LLC and its affiliates. All rights reserved.
Your use of this SDK, sample, or tool is subject to HTC VIVE SDK License Agreement, available at https://developer.vive.com/resources/downloads/licenses-and-agreements/

View File

@@ -1,10 +1,10 @@
# VIVE OpenXR Plugin - Windows # VIVE OpenXR Plugin
The "VIVE OpenXR Plugin - Windows" plugin package contains some OpenXR Unity features for developers to use. The "VIVE OpenXR Plugin" plugin package contains some OpenXR Unity features for developers to use.
## How to install: ## How to install:
### 1. Download the unitypackage from the github. ### 1. Download the unitypackage from the github.
https://github.com/ViveSoftware/VIVE-OpenXR-PC/blob/master/Installer/ViveOpenXRInstaller.unitypackage https://github.com/ViveSoftware/VIVE-OpenXR/blob/master/Installer/ViveOpenXRInstaller.unitypackage
### 2. Import the unitypackage file in the Unity editor. ### 2. Import the unitypackage file in the Unity editor.
### 3. Select the menu on the Unity UI "VIVE/OpenXR_PC Installer", press "Install or Update latest version". ### 3. Select the menu on the Unity UI "VIVE/OpenXR Installer", press "Install or Update latest version".
Note: For "Install specific version", please copy the release version from https://github.com/ViveSoftware/VIVE-OpenXR-PC/releases, Note: For "Install specific version", please copy the release version from https://github.com/ViveSoftware/VIVE-OpenXR/releases,
then paste the version(for example: "1.0.12") to install the specific version. then paste the version(for example: "1.0.12") to install the specific version.

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,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 28769a4eba0d8bf448df06f6edc80599 guid: aae4484d37f3dc949851ce06e791456e
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@@ -0,0 +1,358 @@
// Copyright HTC Corporation All Rights Reserved.
using System;
using System.IO;
using System.Reflection;
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 UnityEngine.XR.OpenXR.Features.Interactions;
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 enableHandtracking = false;
bool enableTracker = false;
bool enableEyetracking = false;
bool enableLipexpression = false;
const string kHandTrackingExtension = "XR_EXT_hand_tracking";
const string kFacialTrackingExtension = "XR_HTC_facial_tracking";
const string kHandInteractionHTC = "XR_HTC_hand_interaction";
const string kHandInteractionEXT = "XR_EXT_hand_interaction";
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
if (null == settings)
return;
foreach (var feature in settings.GetFeatures<OpenXRInteractionFeature>())
{
if ((feature is ViveWristTracker || feature is ViveXRTracker) && feature.enabled)
{
enableHandtracking = true;
enableTracker = true;
}
if (feature is EyeGazeInteraction && feature.enabled)
{
enableEyetracking = true;
}
if (feature is ViveHandInteraction && feature.enabled)
{
enableHandtracking = true;
}
}
foreach (var feature in settings.GetFeatures<OpenXRFeature>())
{
if (!feature.enabled) { continue; }
FieldInfo fieldInfoOpenXrExtensionStrings = typeof(OpenXRFeature).GetField(
"openxrExtensionStrings",
BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfoOpenXrExtensionStrings != null)
{
var openXrExtensionStringsArray =
((string)fieldInfoOpenXrExtensionStrings.GetValue(feature)).Split(' ');
foreach (string stringItem in openXrExtensionStringsArray)
{
if (string.IsNullOrEmpty(stringItem)) { continue; }
if (stringItem.Equals(kHandTrackingExtension) ||
stringItem.Equals(kHandInteractionHTC) ||
stringItem.Equals(kHandInteractionEXT))
{
enableHandtracking = true;
}
if (stringItem.Equals(kFacialTrackingExtension))
{
enableEyetracking = true;
enableLipexpression = true;
}
}
}
}
if (enableHandtracking)
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.handtracking"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
if (enableTracker)
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.tracker"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
if (enableEyetracking)
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.eyetracking"));
newUsesFeature.Attributes.Append(CreateAndroidAttribute("required", "true"));
ManifestElement.AppendChild(newUsesFeature);
}
if (enableLipexpression)
{
var newUsesFeature = CreateElement("uses-feature");
newUsesFeature.Attributes.Append(CreateAndroidAttribute("name", "wave.feature.lipexpression"));
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 fileFormatVersion: 2
guid: b9da6a2c254e9354891b5ab88cd630f0 guid: cd029ee7a3204f446b0def5eafc0a380
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

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

View File

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

View File

@@ -0,0 +1,634 @@
// "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_isExternalSurface = "isExternalSurface";
static GUIContent Label_isExternalSurface = new GUIContent("External Surface", "Specify using external surface or not.");
SerializedProperty Property_isExternalSurface;
static string PropertyName_ExternalSurfaceWidth = "externalSurfaceWidth";
static GUIContent Label_ExternalSurfaceWidth = new GUIContent("Width");
SerializedProperty Property_ExternalSurfaceWidth;
static string PropertyName_ExternalSurfaceHeight = "externalSurfaceHeight";
static GUIContent Label_ExternalSurfaceHeight = new GUIContent("Height");
SerializedProperty Property_ExternalSurfaceHeight;
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_IsCustomRects = "isCustomRects";
static GUIContent Label_IsCustomRects = new GUIContent("Customize Rects", "Using a single texture as a stereo image");
SerializedProperty Property_IsCustomRects;
static string PropertyName_CustomRects = "customRects";
static GUIContent Label_CustomRects = new GUIContent("Customize Rects Type", "Specify the customize rects type of the left texture.");
SerializedProperty Property_CustomRects;
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_SolidEffect = "solidEffect";
static GUIContent Label_SolidEffect = new GUIContent("Solid Effect", "Apply UnderLay Color Scale Bias in Runtime Level.");
SerializedProperty Property_SolidEffect;
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;
//private bool showExternalSurfaceParams = false;
Rect FullRect = new Rect(0, 0, 1, 1);
Rect LeftRightRect = new Rect(0, 0, 0.5f, 1);
Rect TopDownRect = new Rect(0, 0.5f, 1, 0.5f);
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_CustomRects == null) Property_CustomRects = serializedObject.FindProperty(PropertyName_CustomRects);
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_isExternalSurface == null) Property_isExternalSurface = serializedObject.FindProperty(PropertyName_isExternalSurface);
if (Property_ExternalSurfaceWidth == null) Property_ExternalSurfaceWidth = serializedObject.FindProperty(PropertyName_ExternalSurfaceWidth);
if (Property_ExternalSurfaceHeight == null) Property_ExternalSurfaceHeight = serializedObject.FindProperty(PropertyName_ExternalSurfaceHeight);
if (Property_IsDynamicLayer == null) Property_IsDynamicLayer = serializedObject.FindProperty(PropertyName_IsDynamicLayer);
if (Property_IsCustomRects == null) Property_IsCustomRects = serializedObject.FindProperty(PropertyName_IsCustomRects);
if (Property_ApplyColorScaleBias == null) Property_ApplyColorScaleBias = serializedObject.FindProperty(PropertyName_ApplyColorScaleBias);
if (Property_SolidEffect == null) Property_SolidEffect = serializedObject.FindProperty(PropertyName_SolidEffect);
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"))
{
Rect srcRectLeft = FullRect;
if (targetCompositionLayer.isCustomRects && targetCompositionLayer.customRects == CompositionLayer.CustomRectsType.LeftRight)
srcRectLeft = LeftRightRect;
if (targetCompositionLayer.isCustomRects && targetCompositionLayer.customRects == CompositionLayer.CustomRectsType.TopDown)
srcRectLeft = TopDownRect;
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;
cylinderMeshRenderer.sharedMaterial.mainTextureOffset = srcRectLeft.position;
cylinderMeshRenderer.sharedMaterial.mainTextureScale = srcRectLeft.size;
}
//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"))
{
Rect srcRectLeft = FullRect;
if (targetCompositionLayer.isCustomRects && targetCompositionLayer.customRects == CompositionLayer.CustomRectsType.LeftRight)
srcRectLeft = LeftRightRect;
if (targetCompositionLayer.isCustomRects && targetCompositionLayer.customRects == CompositionLayer.CustomRectsType.TopDown)
srcRectLeft = TopDownRect;
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;
quadMeshRenderer.sharedMaterial.mainTextureOffset = srcRectLeft.position;
quadMeshRenderer.sharedMaterial.mainTextureScale = srcRectLeft.size;
}
//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("Left Texture", "Texture used for the left eye"));
EditorGUI.LabelField(new Rect(labelRect.x + labelRect.width / 2, labelRect.y, labelRect.width / 2, labelRect.height), new GUIContent("Right Texture", "Texture used for the right eye"));
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);
targetCompositionLayer.textureRight = (Texture)EditorGUI.ObjectField(new Rect(textureRect.x + textureRect.width / 2, textureRect.y, 64, textureRect.height), targetCompositionLayer.textureRight, typeof(Texture), true);
if (null == targetCompositionLayer.textureLeft)
{
targetCompositionLayer.texture = targetCompositionLayer.textureRight;
//myScript.textures[1] = right;
}
EditorGUILayout.PropertyField(Property_LayerVisibility, new GUIContent(Label_LayerVisibility));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.PropertyField(Property_IsDynamicLayer, Label_IsDynamicLayer);
serializedObject.ApplyModifiedProperties();
//EditorGUILayout.PropertyField(Property_isExternalSurface, Label_isExternalSurface);
//serializedObject.ApplyModifiedProperties();
//if (targetCompositionLayer.isExternalSurface)
/*if (false)
{
EditorGUI.indentLevel++;
showExternalSurfaceParams = EditorGUILayout.Foldout(showExternalSurfaceParams, "External Surface Parameters");
if (showExternalSurfaceParams)
{
EditorGUILayout.PropertyField(Property_ExternalSurfaceWidth, Label_ExternalSurfaceWidth);
EditorGUILayout.PropertyField(Property_ExternalSurfaceHeight, Label_ExternalSurfaceHeight);
EditorGUILayout.PropertyField(Property_IsProtectedSurface, Label_IsProtectedSurface);
serializedObject.ApplyModifiedProperties();
}
EditorGUI.indentLevel--;
}*/
if (targetCompositionLayer.textureLeft == targetCompositionLayer.textureRight || targetCompositionLayer.textureRight == null)
{
EditorGUILayout.PropertyField(Property_IsCustomRects, Label_IsCustomRects);
serializedObject.ApplyModifiedProperties();
}
if (targetCompositionLayer.isCustomRects)
{
EditorGUILayout.PropertyField(Property_CustomRects, new GUIContent(Label_CustomRects));
serializedObject.ApplyModifiedProperties();
}
EditorGUILayout.Space();
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++;
if (targetCompositionLayer.layerType == CompositionLayer.LayerType.Underlay)
{
EditorGUILayout.PropertyField(Property_SolidEffect, Label_SolidEffect);
serializedObject.ApplyModifiedProperties();
}
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 fileFormatVersion: 2
guid: a99cc2a2471f1e7499276e561bbb8d1e guid: ec04348c6d3a8ce43ada545a76766344
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 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 fileFormatVersion: 2
guid: 03f67eb290fa9f3468b94c84f9f50e84 guid: 222aadbc313466a41bafc2f46013fe3d
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

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,166 @@
// Copyright HTC Corporation All Rights Reserved.
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;
public static class PackageManagerHelper
{
private static bool s_wasPreparing;
private static bool m_wasAdded;
private static bool s_wasRemoved;
private static ListRequest m_listRequest;
private static AddRequest m_addRequest;
private static RemoveRequest m_removeRequest;
private static string s_fallbackIdentifier;
public static bool isPreparingList
{
get
{
if (m_listRequest == null) { return s_wasPreparing = true; }
switch (m_listRequest.Status)
{
case StatusCode.InProgress:
return s_wasPreparing = true;
case StatusCode.Failure:
if (!s_wasPreparing)
{
Debug.LogError("Something wrong when adding package to list. error:" + m_listRequest.Error.errorCode + "(" + m_listRequest.Error.message + ")");
}
break;
case StatusCode.Success:
break;
}
return s_wasPreparing = false;
}
}
public static bool isAddingToList
{
get
{
if (m_addRequest == null) { return m_wasAdded = false; }
switch (m_addRequest.Status)
{
case StatusCode.InProgress:
return m_wasAdded = true;
case StatusCode.Failure:
if (!m_wasAdded)
{
AddRequest request = m_addRequest;
m_addRequest = null;
if (string.IsNullOrEmpty(s_fallbackIdentifier))
{
Debug.LogError("Something wrong when adding package to list. error:" + request.Error.errorCode + "(" + request.Error.message + ")");
}
else
{
Debug.Log("Failed to install package: \"" + request.Error.message + "\". Retry with fallback identifier \"" + s_fallbackIdentifier + "\"");
AddToPackageList(s_fallbackIdentifier);
}
s_fallbackIdentifier = null;
}
break;
case StatusCode.Success:
if (!m_wasAdded)
{
m_addRequest = null;
s_fallbackIdentifier = null;
ResetPackageList();
}
break;
}
return m_wasAdded = false;
}
}
public static bool isRemovingFromList
{
get
{
if (m_removeRequest == null) { return s_wasRemoved = false; }
switch (m_removeRequest.Status)
{
case StatusCode.InProgress:
return s_wasRemoved = true;
case StatusCode.Failure:
if (!s_wasRemoved)
{
var request = m_removeRequest;
m_removeRequest = null;
Debug.LogError("Something wrong when removing package from list. error:" + m_removeRequest.Error.errorCode + "(" + m_removeRequest.Error.message + ")");
}
break;
case StatusCode.Success:
if (!s_wasRemoved)
{
m_removeRequest = null;
ResetPackageList();
}
break;
}
return s_wasRemoved = false;
}
}
public static void PreparePackageList()
{
if (m_listRequest != null) { return; }
m_listRequest = Client.List(true, true);
}
public static void ResetPackageList()
{
s_wasPreparing = false;
m_listRequest = null;
}
public static bool IsPackageInList(string name, out UnityEditor.PackageManager.PackageInfo packageInfo)
{
packageInfo = null;
if (m_listRequest == null || m_listRequest.Result == null) return false;
foreach (var package in m_listRequest.Result)
{
if (package.name.Equals(name))
{
packageInfo = package;
return true;
}
}
return false;
}
public static void AddToPackageList(string identifier, string fallbackIdentifier = null)
{
Debug.Assert(m_addRequest == null);
m_addRequest = Client.Add(identifier);
s_fallbackIdentifier = fallbackIdentifier;
}
public static void RemovePackage(string identifier)
{
Debug.Assert(m_removeRequest == null);
m_removeRequest = Client.Remove(identifier);
}
public static PackageCollection GetPackageList()
{
if (m_listRequest == null || m_listRequest.Result == null)
{
return null;
}
return m_listRequest.Result;
}
}

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: b82495a07a589504fa93324ca990a306 guid: 5f1198e3724eb5b44a705edc6d6bae06
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@@ -0,0 +1,24 @@
// Copyright HTC Corporation All Rights Reserved.
using System;
using UnityEngine;
#if UNITY_EDITOR
namespace VIVE.OpenXR.Editor
{
[Serializable]
public class PreferenceAvatarAsset : ScriptableObject
{
public const string AssetPath = "Assets/VIVE/OpenXR/Preferences/PreferenceAvatarAsset.asset";
// VRM constants
public const string kVrm0Package = "UniVRM-0.109.0_7aff.unitypackage";
public const string kVrm0Asset = "Assets/VRM.meta";
public const string kVrm1Package = "VRM-0.109.0_7aff.unitypackage";
public const string kVrm1Asset = "Assets/VRM10.meta";
public bool SupportVrm0 = false;
public bool SupportVrm1 = false;
}
}
#endif

View File

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

View File

@@ -0,0 +1,296 @@
// Copyright HTC Corporation All Rights Reserved.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEditor.XR.Management.Metadata;
namespace VIVE.OpenXR.Editor
{
[InitializeOnLoad]
public static class ViveOpenXRPreference
{
#region Log
static StringBuilder m_sb = null;
static StringBuilder sb {
get {
if (m_sb == null) { m_sb = new StringBuilder(); }
return m_sb;
}
}
const string LOG_TAG = "VIVE.OpenXR.Editor.ViveOpenXRPreference";
static void DEBUG(StringBuilder msg) { Debug.LogFormat("{0} {1}", LOG_TAG, msg); }
static void ERROR(StringBuilder msg) { Debug.LogErrorFormat("{0} {1}", LOG_TAG, msg); }
#endregion
static ViveOpenXRPreference()
{
EditorApplication.update += OnUpdate;
}
#region Scripting Symbols
internal struct ScriptingDefinedSettings
{
public string[] scriptingDefinedSymbols;
public BuildTargetGroup[] targetGroups;
public ScriptingDefinedSettings(string[] symbols, BuildTargetGroup[] groups)
{
scriptingDefinedSymbols = symbols;
targetGroups = groups;
}
}
const string DEFINE_USE_VRM_0_x = "USE_VRM_0_x";
static readonly ScriptingDefinedSettings m_ScriptDefineSettingVrm0 = new ScriptingDefinedSettings(
new string[] { DEFINE_USE_VRM_0_x, },
new BuildTargetGroup[] { 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]))
{
sb.Clear().Append("AddDefineSymbols() ").Append(setting.scriptingDefinedSymbols[symbol_index]).Append(" to group ").Append(group); DEBUG(sb);
allDefines.Add(setting.scriptingDefinedSymbols[symbol_index]);
}
else
{
sb.Clear().Append("AddDefineSymbols() ").Append(setting.scriptingDefinedSymbols[symbol_index]).Append(" already existed."); DEBUG(sb);
}
}
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]))
{
sb.Clear().Append("RemoveDefineSymbols() ").Append(setting.scriptingDefinedSymbols[symbol_index]).Append(" from group ").Append(group); DEBUG(sb);
allDefines.Remove(setting.scriptingDefinedSymbols[symbol_index]);
}
else
{
sb.Clear().Append("RemoveDefineSymbols() ").Append(setting.scriptingDefinedSymbols[symbol_index]).Append(" already existed."); DEBUG(sb);
}
}
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;
}
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 PreferenceAvatarAsset m_AssetAvatar = null;
static void CheckPreferenceAssets()
{
if (File.Exists(PreferenceAvatarAsset.AssetPath))
{
m_AssetAvatar = AssetDatabase.LoadAssetAtPath(PreferenceAvatarAsset.AssetPath, typeof(PreferenceAvatarAsset)) as PreferenceAvatarAsset;
}
else
{
string folderPath = PreferenceAvatarAsset.AssetPath.Substring(0, PreferenceAvatarAsset.AssetPath.LastIndexOf('/'));
DirectoryInfo folder = Directory.CreateDirectory(folderPath);
sb.Clear().Append("CheckPreferenceAssets() Creates folder: Assets/").Append(folder.Name); DEBUG(sb);
m_AssetAvatar = ScriptableObject.CreateInstance(typeof(PreferenceAvatarAsset)) as PreferenceAvatarAsset;
m_AssetAvatar.SupportVrm0 = false;
m_AssetAvatar.SupportVrm1 = false;
sb.Clear().Append("CheckPreferenceAssets() Creates the asset: ").Append(PreferenceAvatarAsset.AssetPath); DEBUG(sb);
AssetDatabase.CreateAsset(m_AssetAvatar, PreferenceAvatarAsset.AssetPath);
}
}
static void OnUpdate()
{
if (!ViveOpenXRAndroidAssigned) { return; }
CheckPreferenceAssets();
if (m_AssetAvatar)
{
// Adds the script symbol if VRM0 is imported.
if (File.Exists(PreferenceAvatarAsset.kVrm0Asset))
{
if (!HasScriptingDefineSymbols(m_ScriptDefineSettingVrm0))
{
sb.Clear().Append("OnUpdate() Adds m_ScriptDefineSettingVrm0."); DEBUG(sb);
AddScriptingDefineSymbols(m_ScriptDefineSettingVrm0);
}
m_AssetAvatar.SupportVrm0 = true;
}
else
{
if (HasScriptingDefineSymbols(m_ScriptDefineSettingVrm0))
{
sb.Clear().Append("OnUpdate() Removes m_ScriptDefineSettingVrm0."); DEBUG(sb);
RemoveScriptingDefineSymbols(m_ScriptDefineSettingVrm0);
}
m_AssetAvatar.SupportVrm0 = false;
}
m_AssetAvatar.SupportVrm1 = File.Exists(PreferenceAvatarAsset.kVrm1Asset);
}
}
#endregion
#region Preferences
const string kPreferenceName = "VIVE OpenXR";
private static GUIContent m_Vrm0Option = new GUIContent("VRM 0", "Avatar format.");
private static GUIContent m_Vrm1Option = new GUIContent("VRM 1", "Avatar format.");
internal static void ImportModule(string packagePath, bool interactive = false)
{
string target = Path.Combine("Packages/com.htc.upm.vive.openxr/UnityPackages~", packagePath);
sb.Clear().Append("ImportModule: " + target); DEBUG(sb);
AssetDatabase.ImportPackage(target, interactive);
}
static bool avatarOption = true;
#pragma warning disable 0618
[PreferenceItem(kPreferenceName)]
#pragma warning restore 0618
private static void OnPreferencesGUI()
{
if (EditorApplication.isCompiling)
{
EditorGUILayout.LabelField("Compiling...");
return;
}
if (PackageManagerHelper.isAddingToList)
{
EditorGUILayout.LabelField("Installing packages...");
return;
}
if (PackageManagerHelper.isRemovingFromList)
{
EditorGUILayout.LabelField("Removing packages...");
return;
}
PackageManagerHelper.PreparePackageList();
if (PackageManagerHelper.isPreparingList)
{
EditorGUILayout.LabelField("Checking Packages...");
return;
}
CheckPreferenceAssets();
GUIStyle sectionTitleStyle = new GUIStyle(EditorStyles.label);
sectionTitleStyle.fontSize = 16;
sectionTitleStyle.richText = true;
sectionTitleStyle.fontStyle = FontStyle.Bold;
#region Avatar
GUILayout.BeginHorizontal();
GUILayout.Space(10);
GUILayout.Label("Avatar", sectionTitleStyle);
GUILayout.EndHorizontal();
GUIStyle foldoutStyle = EditorStyles.foldout;
foldoutStyle.fontSize = 14;
foldoutStyle.fontStyle = FontStyle.Normal;
GUILayout.BeginHorizontal();
GUILayout.Space(20);
avatarOption = EditorGUILayout.Foldout(avatarOption, "Supported Format", foldoutStyle);
GUILayout.EndHorizontal();
foldoutStyle.fontSize = 12;
foldoutStyle.fontStyle = FontStyle.Normal;
if (m_AssetAvatar && avatarOption)
{
/// VRM 0
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.Space(35);
if (!m_AssetAvatar.SupportVrm0)
{
bool toggled = EditorGUILayout.ToggleLeft(m_Vrm0Option, false, GUILayout.Width(230f));
if (toggled)
{
sb.Clear().Append("OnPreferencesGUI() Adds ").Append(PreferenceAvatarAsset.kVrm0Package); DEBUG(sb);
ImportModule(PreferenceAvatarAsset.kVrm0Package);
}
}
else
{
EditorGUILayout.ToggleLeft(m_Vrm0Option, true, GUILayout.Width(230f));
}
GUILayout.EndHorizontal();
/// VRM 1
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.Space(35);
if (!m_AssetAvatar.SupportVrm1)
{
bool toggled = EditorGUILayout.ToggleLeft(m_Vrm1Option, false, GUILayout.Width(230f));
if (toggled)
{
sb.Clear().Append("OnPreferencesGUI() Adds ").Append(PreferenceAvatarAsset.kVrm1Package); DEBUG(sb);
ImportModule(PreferenceAvatarAsset.kVrm1Package);
}
}
else
{
EditorGUILayout.ToggleLeft(m_Vrm1Option, true, GUILayout.Width(230f));
}
GUILayout.EndHorizontal();
}
#endregion
}
#endregion
}
}
#endif

View File

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

View File

@@ -1,11 +1,11 @@
{ {
"name": "HTC.Vive.OpenXR.Editor", "name": "VIVE.OpenXR.Editor",
"rootNamespace": "HTC.Vive.OpenXR.Editor", "rootNamespace": "",
"references": [ "references": [
"GUID:e40ba710768534012815d3193fa296cb", "VIVE.OpenXR",
"GUID:f9fe0089ec81f4079af78eb2287a6163", "Unity.XR.OpenXR",
"GUID:4847341ff46394e83bb78fbd0652937e", "Unity.XR.OpenXR.Editor",
"GUID:96aa6ba065960476598f8f643e7252b6" "Unity.XR.Management.Editor"
], ],
"includePlatforms": [ "includePlatforms": [
"Editor" "Editor"

View File

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

View File

@@ -0,0 +1,24 @@
// Copyright HTC Corporation All Rights Reserved.
using UnityEditor;
using VIVE.OpenXR.Feature;
namespace VIVE.OpenXR.Editor
{
[CustomEditor(typeof(ViveAnchor))]
internal class ViveAnchorEditor : UnityEditor.Editor
{
private SerializedProperty enablePersistedAnchor;
void OnEnable()
{
enablePersistedAnchor = serializedObject.FindProperty("enablePersistedAnchor");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(enablePersistedAnchor);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9094698271e2abb4ab295256548772c3
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,44 @@
// Copyright HTC Corporation All Rights Reserved.
using UnityEngine;
using UnityEngine.SceneManagement;
#if UNITY_EDITOR
using UnityEditor;
namespace VIVE.OpenXR.Editor
{
public class ViveMenu : UnityEditor.Editor
{
private const string kMenuXR = "VIVE/XR/Convert Main Camera to ViveRig";
[MenuItem(kMenuXR, priority = 101)]
private static void ConvertToViveRig()
{
// 1. Removes default Camera
Camera cam = FindObjectOfType<Camera>();
if (cam != null && cam.transform.parent == null)
{
Debug.Log("ConvertToViveRig() remove " + cam.gameObject.name);
DestroyImmediate(cam.gameObject);
}
// 2. Loads ViveRig
if (GameObject.Find("ViveRig") == null && GameObject.Find("ViveRig(Clone)") == null)
{
GameObject prefab = Resources.Load<GameObject>("Prefabs/ViveRig");
if (prefab != null)
{
Debug.Log("ConvertToViveRig() load " + prefab.name);
GameObject inst = Instantiate(prefab, null);
if (inst != null)
{
inst.name = "ViveRig";
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
}
}
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,64 @@
// Copyright HTC Corporation All Rights Reserved.
using UnityEditor;
using UnityEngine;
using VIVE.OpenXR.Feature;
namespace VIVE.OpenXR.Editor
{
[CustomEditor(typeof(ViveMockRuntime))]
internal class ViveMockRuntimeEditor : UnityEditor.Editor
{
private SerializedProperty enableFuture;
private SerializedProperty enableAnchor;
void OnEnable()
{
enableFuture = serializedObject.FindProperty("enableFuture");
enableAnchor = serializedObject.FindProperty("enableAnchor");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// Show a text field for description
EditorGUILayout.HelpBox("VIVE's mock runtime. Used with OpenXR MockRuntime to test unsupported extensions and features on Editor.", MessageType.Info);
if (GUILayout.Button("Install MockRuntime Library")) {
InstallMockRuntimeLibrary();
}
// check if changed
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(enableFuture);
if (EditorGUI.EndChangeCheck()) {
if (!enableFuture.boolValue) {
enableAnchor.boolValue = false;
}
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(enableAnchor);
if (EditorGUI.EndChangeCheck()) {
if (enableAnchor.boolValue) {
enableFuture.boolValue = true;
}
}
serializedObject.ApplyModifiedProperties();
}
public void InstallMockRuntimeLibrary() {
string sourcePathName = "Packages/com.htc.upm.vive.openxr/MockRuntime~/Win64/ViveMockRuntime.dll";
string destPath = "Assets/Plugins/Win64";
string destPathName = "Assets/Plugins/Win64/ViveMockRuntime.dll";
// check if the folder exists. If not, create it.
if (!System.IO.Directory.Exists(destPath)) {
System.IO.Directory.CreateDirectory(destPath);
}
FileUtil.CopyFileOrDirectory(sourcePathName, destPathName);
AssetDatabase.Refresh();
}
}
}

View File

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

View File

@@ -0,0 +1,45 @@
// 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.openxr.feature.compositionlayer",
"vive.openxr.feature.compositionlayer.cylinder",
"vive.openxr.feature.compositionlayer.colorscalebias",
Tracker.ViveWristTracker.featureId,
Hand.ViveHandInteraction.featureId,
"vive.openxr.feature.foveation",
FacialTracking.ViveFacialTracking.featureId,
PlaneDetection.VivePlaneDetection.featureId,
VivePathEnumeration.featureId,
Feature.ViveAnchor.featureId,
DisplayRefreshRate.ViveDisplayRefreshRate.featureId,
Passthrough.VivePassthrough.featureId,
FirstPersonObserver.ViveFirstPersonObserver.FeatureId,
SecondaryViewConfiguration.ViveSecondaryViewConfiguration.FeatureId,
UserPresence.ViveUserPresence.featureId,
CompositionLayer.ViveCompositionLayerExtraSettings.featureId,
FrameSynchronization.ViveFrameSynchronization.featureId,
EyeTracker.ViveEyeTracker.featureId,
Feature.ViveMockRuntime.featureId,
Interaction.ViveInteractions.featureId,
},
UiName = "VIVE XR Support",
Description = "Necessary to deploy an VIVE XR compatible app.",
FeatureSetId = "com.htc.vive.openxr.featureset.vivexr",
#if UNITY_ANDROID
DefaultFeatureIds = new string[] { VIVEFocus3Feature.featureId, VIVEFocus3Profile.featureId, },
#endif
SupportedBuildTargets = new BuildTargetGroup[] { BuildTargetGroup.Android, BuildTargetGroup.Standalone }
)]
sealed class ViveOpenXRFeatureSet { }
}
#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,81 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEditor.XR.OpenXR.Features;
using UnityEngine.XR.OpenXR.Features;
using UnityEngine.XR.OpenXR;
using static VIVE.OpenXR.VIVEFocus3Feature;
namespace VIVE.OpenXR.Editor
{
public class ViveSpectatorCameraProcess : OpenXRFeatureBuildHooks
{
public override int callbackOrder => 1;
public override Type featureType => typeof(VIVEFocus3Feature);
/// <summary>
/// Enable or disable the "First Person Observer" extension according to the Spectator Camera Feature.
/// </summary>
/// <param name="enable">Type True if Spectator Camera Feature is enabled. Otherwise, type False.</param>
private static void SetFirstPersonObserver(in bool enable)
{
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Android);
foreach (OpenXRFeature feature in settings.GetFeatures<OpenXRFeature>())
{
FieldInfo fieldInfoOpenXrExtensionStrings = typeof(OpenXRFeature).GetField(
"openxrExtensionStrings",
BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfoOpenXrExtensionStrings != null)
{
var openXrExtensionStringsArray =
((string)fieldInfoOpenXrExtensionStrings.GetValue(feature)).Split(' ');
foreach (var stringItem in openXrExtensionStringsArray)
{
if (string.IsNullOrEmpty(stringItem))
{
continue;
}
if (!string.Equals(stringItem, FirstPersonObserver.ViveFirstPersonObserver.OPEN_XR_EXTENSION_STRING))
{
continue;
}
feature.enabled = enable;
return;
}
}
}
}
#region The callbacks during the build process when your OpenXR Extension is enabled.
protected override void OnPreprocessBuildExt(BuildReport report)
{
if (IsViveSpectatorCameraEnabled())
{
SetFirstPersonObserver(true);
UnityEngine.Debug.Log("Enable \"First Person Observer\" extension due to the Spectator Camera Feature.");
}
else
{
SetFirstPersonObserver(false);
UnityEngine.Debug.Log("Disable \"First Person Observer\" extension because Spectator Camera Feature is closed.");
}
}
protected override void OnPostGenerateGradleAndroidProjectExt(string path)
{
}
protected override void OnPostprocessBuildExt(BuildReport report)
{
}
#endregion
}
}

View File

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

View File

@@ -1,18 +0,0 @@
{
"name": "HTC.VIVE.OPENXR",
"rootNamespace": "",
"references": [
"GUID:4847341ff46394e83bb78fbd0652937e",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:96aa6ba065960476598f8f643e7252b6"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
Copyright © HTC Corporation, LLC and its affiliates. All rights reserved.
Your use of this SDK, sample, or tool is subject to HTC VIVE SDK License Agreement, available at https://developer.vive.com/resources/downloads/licenses-and-agreements/

View File

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

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: 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,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,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:

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