public unsafe override void GetFaceMesh( TrackableId faceId, Allocator allocator, ref XRFaceMesh faceMesh) { int vertexCount, triangleCount; void *vertexPtr, indexPtr, uvPtr; var faceAnchor = UnityARKit_FaceProvider_AcquireFaceAnchor( faceId, out vertexPtr, out uvPtr, out vertexCount, out indexPtr, out triangleCount); if (faceAnchor == null) { faceMesh.Dispose(); faceMesh = default(XRFaceMesh); return; } try { faceMesh.Resize( vertexCount, triangleCount, XRFaceMesh.Attributes.UVs, allocator); var vertexJob = new TransformVerticesJob { // Use a Vector4 b/c the data is a simd primitive, // so we need something that consists of 4 floats verticesIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector4>(vertexPtr, vertexCount, Allocator.None), verticesOut = faceMesh.vertices }; var vertexJobHandle = vertexJob.Schedule(vertexCount, 32); var uvJob = new TransformUVsJob { uvsIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector2>(uvPtr, vertexCount, Allocator.None), uvsOut = faceMesh.uvs }; var uvJobHandle = uvJob.Schedule(vertexCount, 32); var indexJob = new TransformIndicesJob { triangleIndicesIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Triangle <short> >(indexPtr, triangleCount, Allocator.None), // "cast" it to an array of Triangles triangleIndicesOut = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Triangle <int> >(faceMesh.indices.GetUnsafePtr(), triangleCount, Allocator.None) }; var indexJobHandle = indexJob.Schedule(triangleCount, 32); // Wait on all three JobHandle.CombineDependencies(vertexJobHandle, indexJobHandle, uvJobHandle).Complete(); } finally { UnityARKit_FaceProvider_ReleaseFaceAnchor(faceAnchor); } }
public unsafe override void GetFaceMesh( TrackableId faceId, Allocator allocator, ref XRFaceMesh faceMesh) { int vertexCount, triangleCount; void *vertexPtr, normalPtr, indexPtr, uvPtr; if (!UnityARCore_faceTracking_TryGetFaceData( faceId, out vertexPtr, out normalPtr, out uvPtr, out vertexCount, out indexPtr, out triangleCount)) { faceMesh.Dispose(); faceMesh = default(XRFaceMesh); return; } faceMesh.Resize( vertexCount, triangleCount, XRFaceMesh.Attributes.Normals | XRFaceMesh.Attributes.UVs, allocator); var vertexJobHandle = new TransformVerticesJob { verticesIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector3>(vertexPtr, vertexCount, Allocator.None), verticesOut = faceMesh.vertices }.Schedule(vertexCount, 32); var normalJobHandle = new TransformVerticesJob { verticesIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector3>(normalPtr, vertexCount, Allocator.None), verticesOut = faceMesh.normals }.Schedule(vertexCount, 32); var uvJobHandle = new TransformUVsJob { uvsIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Vector2>(uvPtr, vertexCount, Allocator.None), uvsOut = faceMesh.uvs }.Schedule(vertexCount, 32); var indexJobHandle = new TransformIndicesJob { triangleIndicesIn = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Triangle <ushort> >(indexPtr, triangleCount, Allocator.None), // "cast" it to an array of Triangles triangleIndicesOut = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Triangle <int> >(faceMesh.indices.GetUnsafePtr(), triangleCount, Allocator.None) }.Schedule(triangleCount, 32); // Wait on all four JobHandle.CombineDependencies( JobHandle.CombineDependencies(vertexJobHandle, normalJobHandle), indexJobHandle, uvJobHandle).Complete(); }