internal unsafe void Init(int _maxCount, bool _need3D) { context = default(HandLib.Context); context.minHandSize = 60; context.maxCount = (UInt16)_maxCount; storage = new HandData[context.maxCount]; need3D = _need3D; string str = Application.persistentDataPath; fixed(byte *path = context.modelPath.folderPath) { for (int i = 0; i < str.Length; i++) { path[i] = (byte)str[i]; } } HandLib.Init(ref context); if (need3D) { Hand3DLib.Init(ref context3D); } }
unsafe IEnumerable <T> ITranslator.Fetch <T>(IEnumerable <T> result) { // Only `HandData` can be fetched if (typeof(T) != typeof(HandData)) { throw new NotSupportedException($"Available types: `{typeof(HandData).FullName}`"); } // this code doesn't implement memory reusage Profiler.BeginSample("HandTranslator.Fetch"); // apply 3D fitting for each hands if needed if (need3D && ReadWebcam.instance.prepared) { Hand3DLib.SetCameraInfo(ref context3D, (UInt16)ReadWebcam.instance.current.requestedWidth, (UInt16)ReadWebcam.instance.current.requestedHeight, (UInt16)Screen.width, (UInt16)Screen.height); fixed(HandData *hands = storage) { for (var i = 0; i < count; ++i) { Hand3DLib.Process(ref context3D, ref storage[i]); } for (var p = 0; p < HandData.NumPoints; ++p) { hands[0].Points[p] *= 10; } } } Profiler.EndSample(); // segment of reserved storage return(result = new ArraySegment <HandData>(storage, 0, count) as IEnumerable <HandData> // double casting. as IEnumerable <T>); // usually this is bad }
unsafe Task <ITranslator> IDetectService.Detect(ref ImageData image) { Profiler.BeginSample("HandService.DetectAsync"); // too small image if (image.WebcamWidth < 40) { Debug.LogWarning("HandService.DetectAsync: image is too small"); goto DetectDone; } if (promise != null) { promise.TrySetCanceled(); // the number of detected hands fixed(HandData *handPtr = translator.storage) { translator.count = (UInt16)HandLib.Detect(ref translator.context, ref image, handPtr); } DetectDone: // return result in translator form promise = new TaskCompletionSource <ITranslator>(); promise.SetResult(translator); Profiler.EndSample(); return(promise.Task); } void IDisposable.Dispose() { Debug.LogWarning("HandService.Dispose"); HandLib.Release(ref translator.context); if (need3D) { Hand3DLib.Release(ref translator.context3D); } if (promise == null) return; } promise.TrySetCanceled(); promise = null; }