internal static void ToARFoundationFace(this ARFace face, XRFaceSubsystem xrFaceSubsystem, ref ARFoundationFace arFoundationFace) { if (arFoundationFace == null) { arFoundationFace = new ARFoundationFace(face.trackableId.ToMarsId()); } arFoundationFace.pose = face.transform.GetWorldPose(); var indices = face.indices; if (indices.Length > 0) { k_Vector3Buffer.Clear(); foreach (var vertex in face.vertices) { k_Vector3Buffer.Add(vertex); } arFoundationFace.Mesh.SetVertices(k_Vector3Buffer); k_Vector3Buffer.Clear(); foreach (var normal in face.normals) { k_Vector3Buffer.Add(normal); } arFoundationFace.Mesh.SetNormals(k_Vector3Buffer); k_Vector2Buffer.Clear(); foreach (var uv in face.uvs) { k_Vector2Buffer.Add(uv); } arFoundationFace.Mesh.SetUVs(0, k_Vector2Buffer); k_IntBuffer.Clear(); foreach (var index in indices) { k_IntBuffer.Add(index); } arFoundationFace.Mesh.SetTriangles(k_IntBuffer, 0); #if !UNITY_EDITOR #if UNITY_IOS && INCLUDE_ARKIT_FACE_PLUGIN // For iOS, we use ARKit Face Blendshapes to determine expressions arFoundationFace.GenerateLandmarks(); arFoundationFace.CalculateExpressions(xrFaceSubsystem, face.trackableId); #elif UNITY_ANDROID // For Android, we use the position of the face landmarks to determine expressions arFoundationFace.GenerateLandmarks(); arFoundationFace.CalculateExpressions(ARCoreFaceLandmarksExtensions.LandmarkPositions); #endif #endif } }
/// <summary> /// Shutsdown the provider, removes the XRFaceSubsystem implementation and disposes of the memory used by static arrays. /// </summary> public override void Destroy() { s_CurrentInstance = null; UnityARKit_FaceProvider_Shutdown(); #if UNITY_2019_2_OR_NEWER m_Running = false; #endif }
static void GetFaceBlendShapes(XRFaceSubsystem xrFaceSubsystem, TrackableId faceId, Dictionary <string, float> blendshapes) { var arKitFaceSubsystem = (ARKitFaceSubsystem)xrFaceSubsystem; blendshapes.Clear(); using (var blendShapeCoefficients = arKitFaceSubsystem.GetBlendShapeCoefficients(faceId, Allocator.Temp)) { foreach (var featureCoefficient in blendShapeCoefficients) { blendshapes[featureCoefficient.blendShapeLocation.ToString()] = featureCoefficient.coefficient; } } }
void OnEnable() { var faceManager = FindObjectOfType <ARFaceManager>(); if (faceManager != null && faceManager.subsystem != null && faceManager.descriptor.supportsEyeTracking) { m_FaceSubsystem = (XRFaceSubsystem)faceManager.subsystem; SetVisible((m_Face.trackingState == TrackingState.Tracking) && (ARSession.state > ARSessionState.Ready)); m_Face.updated += OnUpdated; } else { enabled = false; } }
internal void UpdateMesh(XRFaceSubsystem subsystem) { subsystem.GetFaceMesh(sessionRelativeData.trackableId, Allocator.Persistent, ref m_FaceMesh); m_Updated = true; }
static NativeArray <ARKitBlendShapeCoefficient> GetCoefficients(UnityEngine.XR.ARSubsystems.TrackableId id, XRFaceSubsystem subsystem) { #if UNITY_EDITOR if (subsystem is ARKitFaceRemoteSubsystem) { return(((ARKitFaceRemoteSubsystem)subsystem).GetBlendShapeCoefficients(id, Allocator.Temp)); } #else if (subsystem is ARKitFaceSubsystem) { return(((ARKitFaceSubsystem)subsystem).GetBlendShapeCoefficients(id, Allocator.Temp)); } #endif return(default(NativeArray <ARKitBlendShapeCoefficient>)); }
internal static void CalculateExpressions(this ARFoundationFace arFoundationFace, XRFaceSubsystem xrFaceSubsystem, TrackableId faceId) { GetFaceBlendShapes(xrFaceSubsystem, faceId, k_BlendShapes); var expressions = arFoundationFace.Expressions; expressions[MRFaceExpression.LeftEyeClose] = k_LeftEyeClose.Update(k_BlendShapes); expressions[MRFaceExpression.RightEyeClose] = k_RightEyeClose.Update(k_BlendShapes); expressions[MRFaceExpression.LeftEyebrowRaise] = k_LeftBrowRaise.Update(k_BlendShapes); expressions[MRFaceExpression.RightEyebrowRaise] = k_RightBrowRaise.Update(k_BlendShapes); expressions[MRFaceExpression.BothEyebrowsRaise] = k_BothBrowsRaise.Update(k_BlendShapes); expressions[MRFaceExpression.LeftLipCornerRaise] = k_LeftLipCornerRaise.Update(k_BlendShapes); expressions[MRFaceExpression.RightLipCornerRaise] = k_RightLipCornerRaise.Update(k_BlendShapes); expressions[MRFaceExpression.Smile] = k_Smile.Update(k_BlendShapes); expressions[MRFaceExpression.MouthOpen] = k_MouthOpen.Update(k_BlendShapes); }
/// <summary> /// Constructs the XRFaceSubsystem implementation and static native arrays and initializes the provider. /// </summary> public ARKitFaceSubsystem() { s_CurrentInstance = this; UnityARKit_FaceProvider_Initialize(); }
/// <summary> /// Shutsdown the provider, removes the XRFaceSubsystem implementation and disposes of the memory used by static arrays. /// </summary> public override void Destroy() { s_CurrentInstance = null; UnityARKit_FaceProvider_Shutdown(); }