Manipulation gesture:保持点击手势,在3D世界中绝对运动

当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动、缩放或旋转全息图像。如此的一个用处是使得用户可以在世界中绘制图像或作画。使用所有的手势时,操纵手势的初始目标应该通过凝视来选中。一旦点击手势开始,通过手部移动的任何对对象的操作都能够被处理,在用户操作全息图像时,从而使得用户得以自由地四处张望。

1、修改HandsManager.cs,添加InteractionManager.SourcePressed,InteractionManager.SourceReleased处理函数,用于识别物体被点击和被释放的事件

HandsManager.cs完整代码如下:

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3.  
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.VR.WSA.Input;
  7.  
  8. namespace HoloToolkit.Unity
  9. {
  10. /// <summary>
  11. /// HandsManager determines if the hand is currently detected or not.
  12. /// </summary>
  13. public partial class HandsManager : Singleton<HandsManager>
  14. {
  15. /// <summary>
  16. /// HandDetected tracks the hand detected state.
  17. /// Returns true if the list of tracked hands is not empty.
  18. /// </summary>
  19. public bool HandDetected
  20. {
  21. get { return trackedHands.Count > ; }
  22. }
  23.  
  24. private HashSet<uint> trackedHands = new HashSet<uint>();
  25.  
  26. public GameObject FocusedGameObject { get; private set; }
  27.  
  28. void Awake()
  29. {
  30. //识别到来源
  31. InteractionManager.SourceDetected += InteractionManager_SourceDetected;
  32. //来源丢失
  33. InteractionManager.SourceLost += InteractionManager_SourceLost;
  34. //来源被按下
  35. InteractionManager.SourcePressed += InteractionManager_SourcePressed;
  36. //被释放
  37. InteractionManager.SourceReleased += InteractionManager_SourceReleased;
  38. FocusedGameObject = null;
  39. }
  40.  
  41. private void InteractionManager_SourceDetected(InteractionSourceState state)
  42. {
  43. // Check to see that the source is a hand.
  44. if (state.source.kind != InteractionSourceKind.Hand)
  45. {
  46. return;
  47. }
  48.  
  49. trackedHands.Add(state.source.id);
  50. }
  51.  
  52. private void InteractionManager_SourceLost(InteractionSourceState state)
  53. {
  54. // Check to see that the source is a hand.
  55. if (state.source.kind != InteractionSourceKind.Hand)
  56. {
  57. return;
  58. }
  59.  
  60. if (trackedHands.Contains(state.source.id))
  61. {
  62. trackedHands.Remove(state.source.id);
  63. }
  64. FocusedGameObject = null;
  65. }
  66.  
  67. //手势释放时,将被关注的物体置空
  68. private void InteractionManager_SourceReleased(InteractionSourceState state)
  69. {
  70. FocusedGameObject = null;
  71. }
  72.  
  73. //识别到手指按下时,将凝视射线关注的物体置为当前手势操作的对象
  74. private void InteractionManager_SourcePressed(InteractionSourceState state)
  75. {
  76. if (GazeManager.Instance.FocusedObject != null)
  77. {
  78. FocusedGameObject = GazeManager.Instance.FocusedObject;
  79. }
  80. }
  81.  
  82. void OnDestroy()
  83. {
  84. InteractionManager.SourceDetected -= InteractionManager_SourceDetected;
  85. InteractionManager.SourceLost -= InteractionManager_SourceLost;
  86. InteractionManager.SourceReleased -= InteractionManager_SourceReleased;
  87. InteractionManager.SourcePressed -= InteractionManager_SourcePressed;
  88. }
  89. }
  90. }

2、修改GestureManager.cs,订阅Manipulation gesture事件

  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3.  
  4. using System;
  5. using UnityEngine;
  6. using UnityEngine.VR.WSA.Input;
  7.  
  8. namespace HoloToolkit.Unity
  9. {
  10. /// <summary>
  11. /// GestureManager creates a gesture recognizer and signs up for a tap gesture.
  12. /// When a tap gesture is detected, GestureManager uses GazeManager to find the game object.
  13. /// GestureManager then sends a message to that game object.
  14. /// </summary>
  15. [RequireComponent(typeof(GazeManager))]
  16. public partial class GestureManager : Singleton<GestureManager>
  17. {
  18. /// <summary>
  19. /// Key to press in the editor to select the currently gazed hologram
  20. /// </summary>
  21. public KeyCode EditorSelectKey = KeyCode.Space;
  22.  
  23. /// <summary>
  24. /// To select even when a hologram is not being gazed at,
  25. /// set the override focused object.
  26. /// If its null, then the gazed at object will be selected.
  27. /// </summary>
  28. public GameObject OverrideFocusedObject
  29. {
  30. get; set;
  31. }
  32.  
  33. public bool IsManipulating { get; private set; }
  34. public Vector3 ManipulationPosition { get; private set; }
  35.  
  36. /// <summary>
  37. /// Gets the currently focused object, or null if none.
  38. /// </summary>
  39. public GameObject FocusedObject
  40. {
  41. get { return focusedObject; }
  42. }
  43.  
  44. private GestureRecognizer gestureRecognizer;
  45. private GameObject focusedObject;
  46.  
  47. void Start()
  48. {
  49. // Create a new GestureRecognizer. Sign up for tapped events.
  50. gestureRecognizer = new GestureRecognizer();
  51. gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap
  52. | GestureSettings.DoubleTap
  53. | GestureSettings.ManipulationTranslate);
  54.  
  55. gestureRecognizer.TappedEvent += GestureRecognizer_TappedEvent;
  56. //订阅Manipulation gesture事件
  57. gestureRecognizer.ManipulationStartedEvent += GestureRecognizer_ManipulationStartedEvent;
  58. gestureRecognizer.ManipulationUpdatedEvent += GestureRecognizer_ManipulationUpdatedEvent;
  59. gestureRecognizer.ManipulationCompletedEvent += GestureRecognizer_ManipulationCompletedEvent;
  60. gestureRecognizer.ManipulationCanceledEvent += GestureRecognizer_ManipulationCanceledEvent;
  61.  
  62. // Start looking for gestures.
  63. gestureRecognizer.StartCapturingGestures();
  64. }
  65.  
  66. private void GestureRecognizer_ManipulationStartedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)
  67. {
  68. //当被关注的对象非空时,设置初始位置
  69. if (HandsManager.Instance.FocusedGameObject != null)
  70. {
  71. IsManipulating = true;
  72.  
  73. ManipulationPosition = cumulativeDelta;
  74.  
  75. HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationStart", cumulativeDelta);
  76. }
  77. }
  78.  
  79. private void GestureRecognizer_ManipulationUpdatedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)
  80. {
  81. //当被关注的对象非空时,更新新的位置
  82. if (HandsManager.Instance.FocusedGameObject != null)
  83. {
  84. IsManipulating = true;
  85.  
  86. ManipulationPosition = cumulativeDelta;
  87.  
  88. HandsManager.Instance.FocusedGameObject.SendMessageUpwards("PerformManipulationUpdate", cumulativeDelta);
  89. }
  90. }
  91.  
  92. private void GestureRecognizer_ManipulationCompletedEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)
  93. {
  94. IsManipulating = false;
  95. }
  96.  
  97. private void GestureRecognizer_ManipulationCanceledEvent(InteractionSourceKind source, Vector3 cumulativeDelta, Ray headRay)
  98. {
  99. IsManipulating = false;
  100. }
  101.  
  102. private void OnTap()
  103. {
  104. if (focusedObject != null)
  105. {
  106. focusedObject.SendMessage("OnTap");
  107. }
  108. }
  109.  
  110. private void OnDoubleTap()
  111. {
  112. if (focusedObject != null)
  113. {
  114. focusedObject.SendMessage("OnDoubleTap");
  115. }
  116. }
  117.  
  118. private void GestureRecognizer_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay)
  119. {
  120. if (tapCount == )
  121. {
  122. OnTap();
  123. }
  124. else
  125. {
  126. OnDoubleTap();
  127. }
  128. }
  129.  
  130. void LateUpdate()
  131. {
  132. GameObject oldFocusedObject = focusedObject;
  133.  
  134. if (GazeManager.Instance.Hit &&
  135. OverrideFocusedObject == null &&
  136. GazeManager.Instance.HitInfo.collider != null)
  137. {
  138. // If gaze hits a hologram, set the focused object to that game object.
  139. // Also if the caller has not decided to override the focused object.
  140. focusedObject = GazeManager.Instance.HitInfo.collider.gameObject;
  141. }
  142. else
  143. {
  144. // If our gaze doesn't hit a hologram, set the focused object to null or override focused object.
  145. focusedObject = OverrideFocusedObject;
  146. }
  147.  
  148. //if (focusedObject != oldFocusedObject)
  149. //{
  150. // // If the currently focused object doesn't match the old focused object, cancel the current gesture.
  151. // // Start looking for new gestures. This is to prevent applying gestures from one hologram to another.
  152. // gestureRecognizer.CancelGestures();
  153. // gestureRecognizer.StartCapturingGestures();
  154. //}
  155. }
  156.  
  157. void OnDestroy()
  158. {
  159. gestureRecognizer.StopCapturingGestures();
  160. //取消订阅
  161. gestureRecognizer.TappedEvent -= GestureRecognizer_TappedEvent;
  162. gestureRecognizer.ManipulationStartedEvent -= GestureRecognizer_ManipulationStartedEvent;
  163. gestureRecognizer.ManipulationUpdatedEvent -= GestureRecognizer_ManipulationUpdatedEvent;
  164. gestureRecognizer.ManipulationCompletedEvent -= GestureRecognizer_ManipulationCompletedEvent;
  165. gestureRecognizer.ManipulationCanceledEvent -= GestureRecognizer_ManipulationCanceledEvent;
  166. }
  167. }
  168. }

3、添加ManipulationTranslate脚本,计算相对位移,然后进行更新物体的新的位置。

  1. using UnityEngine;
  2. using System.Collections;
  3. using HoloToolkit.Unity;
  4.  
  5. public class ManipulationTranslate: MonoBehaviour {
  6.  
  7. private Vector3 manipulationPreviousPosition;
  8.  
  9. // Use this for initialization
  10. void Start () {
  11.  
  12. }
  13.  
  14. // Update is called once per frame
  15. void Update () {
  16.  
  17. }
  18.  
  19. void PerformManipulationStart(Vector3 position)
  20. {
  21. //设置初始位置
  22. manipulationPreviousPosition = position;
  23. }
  24.  
  25. void PerformManipulationUpdate(Vector3 position)
  26. {
  27. if (GestureManager.Instance.IsManipulating)
  28. {
  29. //计算相对位移,然后更新物体的位置
  30. Vector3 moveVector = Vector3.zero;
  31. moveVector = position - manipulationPreviousPosition;
  32. manipulationPreviousPosition = position;
  33. transform.position += 2f * moveVector;
  34. }
  35. }

4、运行测试

将凝视射线投射到对象上,举起右手使食指和拇指碰触在一起,然后进行左右移动,可以看到物体的位置将移动。

Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体平移)的更多相关文章

  1. Hololens开发笔记之Gesture手势识别(手势检测反馈)

    本文实现当使用者手出现在Hololens视野范围内时,跟踪手并给出反馈的效果. 1.在Manager上添加HandsManager脚本组件,用于追踪识别手 HandsManager.cs如下(直接使用 ...

  2. Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体旋转)

    Manipulation gesture:保持点击手势,在3D世界中绝对运动 当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动.缩放或旋转全息图像.如此的一个用处是使得用户可以在世界中绘 ...

  3. Hololens开发笔记之Gesture手势识别(单击,双击)

    本文使用手势识别实现识别单击及双击手势的功能,当单击Cube时改变颜色为蓝色,当双击Cube时改变颜色为绿色. 手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层 ...

  4. Hololens开发笔记之Gesture手势识别(基本介绍)

    手势识别是HoloLens交互的重要输入方法之一.HoloLens提供了底层API和高层API,可以满足不同的手势定制需求.底层API能够获取手的位置和速度信息,高层API则借助手势识别器来识别预设的 ...

  5. HoloLens开发笔记之Gesture input手势输入

    手势是HoloLens三个首要输入形式之一.一旦你使用凝视定位了一个全息图像,手势允许你与它交互.手势输入允许你使用手或者点击器原生地与全息图像交互. 手势之外,你也可以在应用中使用语音输入来交互. ...

  6. Hololens开发笔记之使用Unity开发一个简单的应用

    一.Hololens概述 Hololens有以下特性 1.空间映射借助微软特殊定制的全息处理单元(HPU),HoloLens 实现了对周边环境的快速扫描和空间匹配.这保证了 HoloLens能够准确地 ...

  7. Hololens开发笔记之连接PC实现资源共享

    官网原文介绍:https://developer.microsoft.com/en-us/windows/holographic/using_the_windows_device_portal Hol ...

  8. Hololens开发笔记:UDP接收数据

    Hololens的应用需要与其他设备通信的时候,UDP是比较方便的一种方式,Unity3d 2017.3 C#开发的时候可以用Windows.Networking.Sockets.DatagramSo ...

  9. Hololens开发笔记之Gaze凝视射线

    凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 概念上来说,Gaze是通过用户头部两眼之间发出一条向前 ...

随机推荐

  1. Win10/UWP开发-Ink墨迹书写

    在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记. InkCanvas控件使用很简单,从 ...

  2. 传智播客JavaWeb day11--事务的概念、事务的ACID、数据库锁机制、

    1. 什么叫做事务? 2.默认情况下每一条sql语句都是一个事务,然后自动提交事务  ps:如果想多条语句占一个事务,则可以手动设置SetAutoCommit为false 3.关键字 start tr ...

  3. Linux系统下远程文件拷贝scp命令

    在Linux系统下,不同机器上实现文件拷贝 一.将本地文件拷贝到远程机器: scp /home/administrator/news.txt root@192.168.6.129:/etc/squid ...

  4. 必须掌握的八个cmd 命令

    一,ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它 所利用的原理是这样的:网络上的机器都有唯一确定的I ...

  5. declaration is incompatible with "__nounwind __interwork __softfp unsigned long __get_PSP(void)" IAR 编译报故障

    原因是以前的CMSIS  CORTEX-CM0 文件太老了.   使用新文件就可以.

  6. DotNetBar 第1课,设置整体窗口样式

    1. 先引用 DevComponents.DotNetBar2.dll 2. 窗口继承 Office2007Form public partial class Form1 : Office2007Fo ...

  7. 论文ei,sci检索,JCR-SCI分区,中科院分区连接

    https://jcr.incites.thomsonreuters.com/JCRJournalHomeAction.action?SID=B1-bQgax2FJ7EsyZ9muP6O5loc77S ...

  8. 【海洋女神原创】知识普及:IS版本命名规则和高低关系

    经常有朋友对IS的版本命名不甚了解,有时候在交流的时候就会造成误会,在这里做一下普及. IS最早出名的版本是IS6.22,这是个非常古老的版本的,但是在IS历史上有不可磨灭的贡献. 之后很长一段时间内 ...

  9. linux sed和awk的区别

    awkawk是一种程序语言,对文档资料的处理具有很强的功能.awk擅长从格式化报文或从一个大的文本文件中抽取数据.awk的命令格式为:awk [-F filed-separator] “command ...

  10. NSCharacter​Set在字符串操作中得使用

    NSCharacterSet以及它的可变版本NSMutableCharacterSet,用面向对象的方式表示一组Unicode字符,它经常与NSString及NSScanner组合起来使用,在不同的字 ...