UnityTouchlessSession.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Threading;
  4. using TouchlessA3D;
  5. using UnityEngine;
  6. using UnityEngine.UI;
  7. using System.Collections;
  8. //This Monobehaviour manages the connection to the gesture engine and syncs event to the Unity Update loop
  9. //it is better to sync the events before other scripts by setting this first in the Unity Project Settings -> Script Execution Order
  10. public class UnityTouchlessSession : ITouchlessSession
  11. {
  12. public float startDelay = 1.0f;
  13. //subscribe events to the eventhandler with ITouchlessSession.instance.ta3dEventHandler+=functionName;
  14. //if the function is a method, remember to remove the event when the object containing it is destroyed, eg OnDestroyed(){ITouchlessSession.instance.ta3dEventHandler-=functionName}
  15. public UnityCameraIntegration camIntegration;
  16. private WebCamTexture camTex;
  17. private Color32[] imgData = new Color32[UnityCameraIntegration.width * UnityCameraIntegration.height];
  18. private GCHandle handleToData;
  19. private string uniqueID;
  20. private string storageLocation;
  21. private GestureEvent locked_gestureEvent;
  22. private readonly object lockObj = new object();
  23. private Engine touchlessEngine;
  24. private void Awake()
  25. {
  26. if (null == instance)
  27. {
  28. instance = this;
  29. DontDestroyOnLoad(this);
  30. }
  31. else if (this != instance)
  32. {
  33. DestroyImmediate(this);
  34. }
  35. }
  36. private bool isStarted = false;
  37. private IEnumerator Start()
  38. {
  39. yield return new WaitForSeconds(startDelay);
  40. handleToData = GCHandle.Alloc(imgData, GCHandleType.Pinned);
  41. uniqueID = SystemInfo.deviceUniqueIdentifier;
  42. storageLocation = Application.persistentDataPath;
  43. var calibration = new NativeCalibration();
  44. touchlessEngine = new Engine(uniqueID, storageLocation, calibration, TouchlessEvent);
  45. isStarted = true;
  46. }
  47. private void Update()
  48. {
  49. if(!isStarted)
  50. {
  51. return;
  52. }
  53. GestureEvent syncedEvent = null;
  54. lock (lockObj)
  55. {
  56. if (locked_gestureEvent != null)
  57. {
  58. syncedEvent = new GestureEvent(locked_gestureEvent);
  59. locked_gestureEvent = null;
  60. }
  61. }
  62. if (null != syncedEvent && null != ta3dEventHandler)
  63. {
  64. ta3dEventHandler(this, syncedEvent);
  65. }
  66. ProccessOneFrame();
  67. }
  68. private void TouchlessEvent(object sender, GestureEvent args)
  69. {
  70. lock (lockObj)
  71. {
  72. locked_gestureEvent = args;
  73. }
  74. }
  75. private void ProccessOneFrame()
  76. {
  77. if (null == camTex) camTex = camIntegration.cameraTexture;
  78. if (null == camTex || !camTex.didUpdateThisFrame)
  79. {
  80. return;
  81. }
  82. camTex.GetPixels32(imgData);
  83. using (var frame = new TouchlessA3D.Frame(handleToData.AddrOfPinnedObject(), camTex.width * 4,
  84. camTex.width, camTex.height, System.DateTimeOffset.Now.ToUnixTimeMilliseconds(),
  85. FrameRotation.ROTATION_NONE, true))
  86. {
  87. touchlessEngine.handleFrame(frame);
  88. }
  89. }
  90. private void OnApplicationQuit()
  91. {
  92. if (null != handleToData)
  93. {
  94. handleToData.Free();
  95. }
  96. }
  97. }