diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Marshal/NativeLandmark.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Marshal/NativeLandmark.cs index b115df726..56920027c 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Marshal/NativeLandmark.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Marshal/NativeLandmark.cs @@ -79,6 +79,26 @@ public ReadOnlySpan AsReadOnlySpan() } } + [StructLayout(LayoutKind.Sequential)] + internal readonly struct NativeLandmarksArray + { + private readonly IntPtr _data; + public readonly int size; + + public void Dispose() + { + UnsafeNativeMethods.mp_api_LandmarksArray__delete(this); + } + + public ReadOnlySpan AsReadOnlySpan() + { + unsafe + { + return new ReadOnlySpan((NativeLandmarks*)_data, size); + } + } + } + [StructLayout(LayoutKind.Sequential)] internal readonly struct NativeNormalizedLandmarksArray { @@ -87,7 +107,7 @@ internal readonly struct NativeNormalizedLandmarksArray public void Dispose() { - UnsafeNativeMethods.mp_api_NormalizedLandmarksArray__delete(_data, size); + UnsafeNativeMethods.mp_api_NormalizedLandmarksArray__delete(this); } public ReadOnlySpan AsReadOnlySpan() diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Tasks/Components/Containers_Unsafe.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Tasks/Components/Containers_Unsafe.cs index 4f46209f2..06e513d11 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Tasks/Components/Containers_Unsafe.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/PInvoke/NativeMethods/Tasks/Components/Containers_Unsafe.cs @@ -23,10 +23,16 @@ internal static partial class UnsafeNativeMethods [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern void mp_tasks_c_components_containers_CppCloseDetectionResult(NativeDetectionResult data); + [DllImport(MediaPipeLibrary, ExactSpelling = true)] + public static extern MpReturnCode mp_Packet__GetLandmarksVector(IntPtr packet, out NativeLandmarksArray value); + + [DllImport(MediaPipeLibrary, ExactSpelling = true)] + public static extern void mp_api_LandmarksArray__delete(NativeLandmarksArray data); + [DllImport(MediaPipeLibrary, ExactSpelling = true)] public static extern MpReturnCode mp_Packet__GetNormalizedLandmarksVector(IntPtr packet, out NativeNormalizedLandmarksArray value); [DllImport(MediaPipeLibrary, ExactSpelling = true)] - public static extern void mp_api_NormalizedLandmarksArray__delete(IntPtr data, int size); + public static extern void mp_api_NormalizedLandmarksArray__delete(NativeNormalizedLandmarksArray data); } } diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/Landmark.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/Landmark.cs index b236fae63..4012540c6 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/Landmark.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/Landmark.cs @@ -59,6 +59,17 @@ internal Landmark(float x, float y, float z, float? visibility, float? presence, this.name = name; } + internal Landmark(NativeLandmark nativeLandmark) : this( + nativeLandmark.x, nativeLandmark.y, nativeLandmark.z, +#pragma warning disable IDE0004 // for Unity 2020.3.x + nativeLandmark.hasVisibility ? (float?)nativeLandmark.visibility : null, + nativeLandmark.hasPresence ? (float?)nativeLandmark.presence : null, +#pragma warning restore IDE0004 // for Unity 2020.3.x + nativeLandmark.name + ) + { + } + #nullable enable public override bool Equals(object? obj) => obj is Landmark other && Equals(other); #nullable disable @@ -105,17 +116,6 @@ public override string ToString() public readonly float? presence; public readonly string name; - internal NormalizedLandmark(NativeNormalizedLandmark nativeLandmark) : this( - nativeLandmark.x, nativeLandmark.y, nativeLandmark.z, -#pragma warning disable IDE0004 // for Unity 2020.3.x - nativeLandmark.hasVisibility ? (float?)nativeLandmark.visibility : null, - nativeLandmark.hasPresence ? (float?)nativeLandmark.presence : null, -#pragma warning restore IDE0004 // for Unity 2020.3.x - nativeLandmark.name - ) - { - } - internal NormalizedLandmark(float x, float y, float z, float? visibility, float? presence) : this(x, y, z, visibility, presence, null) { } @@ -130,6 +130,17 @@ internal NormalizedLandmark(float x, float y, float z, float? visibility, float? this.name = name; } + internal NormalizedLandmark(NativeNormalizedLandmark nativeLandmark) : this( + nativeLandmark.x, nativeLandmark.y, nativeLandmark.z, +#pragma warning disable IDE0004 // for Unity 2020.3.x + nativeLandmark.hasVisibility ? (float?)nativeLandmark.visibility : null, + nativeLandmark.hasPresence ? (float?)nativeLandmark.presence : null, +#pragma warning restore IDE0004 // for Unity 2020.3.x + nativeLandmark.name + ) + { + } + #nullable enable public override bool Equals(object? obj) => obj is NormalizedLandmark other && Equals(other); #nullable disable @@ -195,6 +206,18 @@ public static void Copy(LandmarkList source, ref Landmarks destination) destination = new Landmarks(landmarks); } + internal static void Copy(NativeLandmarks source, ref Landmarks destination) + { + var landmarks = destination.landmarks ?? new List((int)source.landmarksCount); + landmarks.Clear(); + + foreach (var nativeLandmark in source.AsReadOnlySpan()) + { + landmarks.Add(new Landmark(nativeLandmark)); + } + destination = new Landmarks(landmarks); + } + public override string ToString() => $"{{ \"landmarks\": {Util.Format(landmarks)} }}"; } @@ -247,8 +270,21 @@ internal static void Copy(NativeNormalizedLandmarks source, ref NormalizedLandma public override string ToString() => $"{{ \"landmarks\": {Util.Format(landmarks)} }}"; } - internal static class NativeNormalizedLandmarksArrayExtension + internal static class NativeLandmarksArrayExtension { + public static void FillWith(this List target, NativeLandmarksArray source) + { + target.ResizeTo(source.size); + + var i = 0; + foreach (var nativeLandmarks in source.AsReadOnlySpan()) + { + var landmarks = target[i]; + Landmarks.Copy(nativeLandmarks, ref landmarks); + target[i] = landmarks; + } + } + public static void FillWith(this List target, NativeNormalizedLandmarksArray source) { target.ResizeTo(source.size); diff --git a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs index e27c3ee09..fec167fc8 100644 --- a/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs +++ b/Packages/com.github.homuler.mediapipe/Runtime/Scripts/Tasks/Components/Containers/PacketExtension.cs @@ -25,6 +25,13 @@ public static void GetDetectionResult(this Packet packet, ref DetectionResult va detectionResult.Dispose(); } + public static void GetLandmarksList(this Packet packet, List outs) + { + UnsafeNativeMethods.mp_Packet__GetLandmarksVector(packet.mpPtr, out var landmarksArray).Assert(); + outs.FillWith(landmarksArray); + landmarksArray.Dispose(); + } + public static void GetNormalizedLandmarksList(this Packet packet, List outs) { UnsafeNativeMethods.mp_Packet__GetNormalizedLandmarksVector(packet.mpPtr, out var landmarksArray).Assert(); diff --git a/mediapipe_api/tasks/c/components/containers/landmark.cc b/mediapipe_api/tasks/c/components/containers/landmark.cc index 2195d1e59..a49ab616f 100644 --- a/mediapipe_api/tasks/c/components/containers/landmark.cc +++ b/mediapipe_api/tasks/c/components/containers/landmark.cc @@ -18,10 +18,40 @@ MpReturnCode mp_Packet__GetNormalizedLandmarksVector(mediapipe::Packet* packet, CATCH_ALL } -void mp_api_NormalizedLandmarksArray__delete(NormalizedLandmarks* data, int size) { - auto landmarks = data; +void mp_api_NormalizedLandmarksArray__delete(mp_api::StructArray array) { + auto landmarks = array.data; + auto size = array.size; + for (auto i = 0; i < size; ++i) { mediapipe::tasks::c::components::containers::CppCloseNormalizedLandmarks(landmarks++); } - delete[] data; + delete[] array.data; +} + +MpReturnCode mp_Packet__GetLandmarksVector(mediapipe::Packet* packet, mp_api::StructArray* value_out) { + TRY_ALL + // get std::vector and convert it to Landmarks* + auto proto_vec = packet->Get>(); + auto vec_size = proto_vec.size(); + auto data = new Landmarks[vec_size]; + + for (auto i = 0; i < vec_size; ++i) { + auto landmarks = mediapipe::tasks::components::containers::ConvertToLandmarks(proto_vec[i]); + mediapipe::tasks::c::components::containers::CppConvertToLandmarks(landmarks.landmarks, &data[i]); + } + + value_out->data = data; + value_out->size = static_cast(vec_size); + RETURN_CODE(MpReturnCode::Success); + CATCH_ALL +} + +void mp_api_LandmarksArray__delete(mp_api::StructArray array) { + auto landmarks = array.data; + auto size = array.size; + + for (auto i = 0; i < size; ++i) { + mediapipe::tasks::c::components::containers::CppCloseLandmarks(landmarks++); + } + delete[] array.data; } diff --git a/mediapipe_api/tasks/c/components/containers/landmark.h b/mediapipe_api/tasks/c/components/containers/landmark.h index afd2de02d..6e76e6691 100644 --- a/mediapipe_api/tasks/c/components/containers/landmark.h +++ b/mediapipe_api/tasks/c/components/containers/landmark.h @@ -16,7 +16,9 @@ extern "C" { MP_CAPI(MpReturnCode) mp_Packet__GetNormalizedLandmarksVector(mediapipe::Packet* packet, mp_api::StructArray* value_out); -MP_CAPI(void) mp_api_NormalizedLandmarksArray__delete(NormalizedLandmarks* data, int size); +MP_CAPI(void) mp_api_NormalizedLandmarksArray__delete(mp_api::StructArray data); +MP_CAPI(MpReturnCode) mp_Packet__GetLandmarksVector(mediapipe::Packet* packet, mp_api::StructArray* value_out); +MP_CAPI(void) mp_api_LandmarksArray__delete(mp_api::StructArray data); } // extern "C"