add package files
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7eb9da8a5f7ef3740828986abcac7265
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
//========= 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_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86a415a999d54da45982ad39e33e9ac1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= 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,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37460e91d6cb92340a576dfe03bef2b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,72 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb05e3e629aecd44ebe7dbfc4a7a6d56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,100 @@
|
||||
//========= 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47613961cde0a8b4aa4f79219b7e523c
|
||||
timeCreated: 1545374952
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e820c013bcd10a4ea94b6d91672f893
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,234 @@
|
||||
//========= 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2872c722b18f6d043ad0dbae08561d64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
//========= 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19eff34b54274a84c8b0f87cffbfd76a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 196084005ab84764aac2e78a079dc66c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 412f6d64b6ea21045b60b739f1a83f31
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
//========= 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bc508f7f051e624181e0391cf04db7f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
//========= 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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44593dc2ec4dd36449dfb356ce482a0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91324d258827df746818399b9a51d4d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,103 @@
|
||||
//========= 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41f6d745d46210a49a0df9fe7d0d1102
|
||||
timeCreated: 1545375801
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 846f91cae57562348bd10c1617b45b13
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
//========= 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42350b51669fc604cb2cad73c39f116c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dcb8610a1e4fe94a8cc7983d3b650cb
|
||||
timeCreated: 1545375969
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
//========= Copyright 2019, HTC Corporation. All rights reserved. ===========
|
||||
namespace VIVE
|
||||
{
|
||||
/// <summary>
|
||||
/// error code of ViveSR
|
||||
/// </summary>
|
||||
public enum Error : int
|
||||
{
|
||||
RUNTIME_NOT_FOUND = -3,
|
||||
NOT_INITIAL = -2,
|
||||
FAILED = -1,
|
||||
WORK = 0,
|
||||
INVALID_INPUT = 1,
|
||||
FILE_NOT_FOUND = 2,
|
||||
DATA_NOT_FOUND = 13,
|
||||
UNDEFINED = 319,
|
||||
INITIAL_FAILED = 1001,
|
||||
NOT_IMPLEMENTED = 1003,
|
||||
NULL_POINTER = 1004,
|
||||
OVER_MAX_LENGTH = 1005,
|
||||
FILE_INVALID = 1006,
|
||||
UNINSTALL_STEAM = 1007,
|
||||
MEMCPY_FAIL = 1008,
|
||||
NOT_MATCH = 1009,
|
||||
NODE_NOT_EXIST = 1010,
|
||||
UNKONW_MODULE = 1011,
|
||||
MODULE_FULL = 1012,
|
||||
UNKNOW_TYPE = 1013,
|
||||
INVALID_MODULE = 1014,
|
||||
INVALID_TYPE = 1015,
|
||||
MEMORY_NOT_ENOUGH = 1016,
|
||||
BUSY = 1017,
|
||||
NOT_SUPPORTED = 1018,
|
||||
INVALID_VALUE = 1019,
|
||||
COMING_SOON = 1020,
|
||||
INVALID_CHANGE = 1021,
|
||||
TIMEOUT = 1022,
|
||||
DEVICE_NOT_FOUND = 1023,
|
||||
INVALID_DEVICE = 1024,
|
||||
NOT_AUTHORIZED = 1025,
|
||||
ALREADY = 1026,
|
||||
INTERNAL = 1027,
|
||||
CONNECTION_FAILED = 1028,
|
||||
ALLOCATION_FAILED = 1029,
|
||||
OPERATION_FAILED = 1030,
|
||||
NOT_AVAILABLE = 1031,
|
||||
CALLBACK_IN_PROGRESS= 1032,
|
||||
SERVICE_NOT_FOUND = 1033,
|
||||
DISABLED_BY_USER = 1034,
|
||||
EULA_NOT_ACCEPT = 1035,
|
||||
RUNTIME_NO_RESPONSE = 1036,
|
||||
OPENCL_NOT_SUPPORT = 1037,
|
||||
NOT_SUPPORT_EYE_TRACKING = 1038,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c81a0042ed8435d4097d6717e1b45dd8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user