SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

159 lines
5.8 KiB

using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.ARFoundation
{
/// <summary>
/// Represents a face detected by an AR device.
/// </summary>
/// <remarks>
/// Generated by the <see cref="ARFaceManager"/> when an AR device detects
/// a face in the environment.
/// </remarks>
[DisallowMultipleComponent]
[DefaultExecutionOrder(ARUpdateOrder.k_Face)]
[HelpURL("https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@3.0/api/UnityEngine.XR.ARFoundation.ARFace.html")]
public sealed class ARFace : ARTrackable<XRFace, ARFace>
{
/// <summary>
/// Invoked when the face is updated. If face meshes are supported, there will be
/// updated <see cref="vertices"/>, <see cref="normals"/>, <see cref="indices"/>, and
/// <see cref="uvs"/>.
/// </summary>
public event Action<ARFaceUpdatedEventArgs> updated;
/// <summary>
/// The vertices representing the face mesh. Check for existence with <c>vertices.IsCreated</c>.
/// This array is parallel to <see cref="normals"/> and <see cref="uvs"/>. Vertices are
/// provided in face space, that is, relative to this <see cref="ARFace"/>'s local
/// position and rotation.
/// </summary>
public unsafe NativeArray<Vector3> vertices
{
get
{
return GetUndisposable(m_FaceMesh.vertices);
}
}
/// <summary>
/// The normals representing the face mesh. Check for existence with <c>normals.IsCreated</c>.
/// This array is parallel to <see cref="vertices"/> and <see cref="uvs"/>.
/// </summary>
public unsafe NativeArray<Vector3> normals
{
get
{
return GetUndisposable(m_FaceMesh.normals);
}
}
/// <summary>
/// The indices defining the triangles of the face mesh. Check for existence with <c>indices.IsCreated</c>.
/// The are three times as many indices as triangles, so this will always be a multiple of 3.
/// </summary>
public NativeArray<int> indices
{
get
{
return GetUndisposable(m_FaceMesh.indices);
}
}
/// <summary>
/// The texture coordinates representing the face mesh. Check for existence with <c>uvs.IsCreated</c>.
/// This array is parallel to <see cref="vertices"/> and <see cref="normals"/>.
/// </summary>
public NativeArray<Vector2> uvs
{
get
{
return GetUndisposable(m_FaceMesh.uvs);
}
}
/// <summary>
/// Get a native pointer associated with this face.
/// </summary>
/// <remarks>
/// The data pointed to by this member is implementation defined.
/// The lifetime of the pointed to object is also
/// implementation defined, but should be valid at least until the next
/// <see cref="ARSession"/> update.
/// </remarks>
public IntPtr nativePtr => sessionRelativeData.nativePtr;
/// <summary>
/// The [transform](https://docs.unity3d.com/ScriptReference/Transform.html) of the left eye of the face, or `null` if there is no data for the left eye.
/// </summary>
public Transform leftEye { get; private set; }
/// <summary>
/// The [transform](https://docs.unity3d.com/ScriptReference/Transform.html) of the right eye of the face, or `null` if there is no data for the right eye.
/// </summary>
public Transform rightEye { get; private set; }
/// <summary>
/// The [transform](https://docs.unity3d.com/ScriptReference/Transform.html) representing the point at which the eyes are fixated upon or `null` if there is no fixation data.
/// </summary>
public Transform fixationPoint { get; private set; }
void Update()
{
if (m_Updated && updated != null)
{
updated(new ARFaceUpdatedEventArgs(this));
m_Updated = false;
}
}
void OnDestroy()
{
m_FaceMesh.Dispose();
}
// Creates an alias to the same array, but the caller cannot Dispose it.
unsafe NativeArray<T> GetUndisposable<T>(NativeArray<T> disposable) where T : struct
{
if (!disposable.IsCreated)
return default(NativeArray<T>);
return NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>(
disposable.GetUnsafePtr(),
disposable.Length,
Allocator.None);
}
internal void UpdateMesh(XRFaceSubsystem subsystem)
{
subsystem.GetFaceMesh(sessionRelativeData.trackableId, Allocator.Persistent, ref m_FaceMesh);
m_Updated = true;
}
internal void UpdateEyes()
{
if (leftEye == null && rightEye == null && fixationPoint == null)
{
leftEye = Instantiate(new GameObject(), transform).transform;
rightEye = Instantiate(new GameObject(), transform).transform;
fixationPoint = Instantiate(new GameObject(), transform).transform;
}
UpdateTransformFromPose(leftEye, sessionRelativeData.leftEyePose);
UpdateTransformFromPose(rightEye, sessionRelativeData.rightEyePose);
fixationPoint.localPosition = sessionRelativeData.fixationPoint;
}
private void UpdateTransformFromPose(Transform eyeTransform, Pose eyePose)
{
eyeTransform.localPosition = eyePose.position;
eyeTransform.localRotation = eyePose.rotation;
}
XRFaceMesh m_FaceMesh;
bool m_Updated;
}
}