转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2350

上一篇提到了,KlayGE的输入系统正在大改,将要加入触摸支持。本篇将会介绍Win7的touch,以及简单的手势识别。

Win7 Touch API

实际上Win7开始就支持了多触摸,只是UI和续航没跟上,使得Win7的平板体验一般。Win7的touch分为两个层面,第一个是底层的WM_TOUCH消息,应用程序收到的是触点坐标等;第二个是高层的WM_GESTURE消息,应用程序收到的就是已经经过识别的手势了。两者只能选择一个,不能两个都收到。默认的是WM_GESTURE,如果调用了RegisterTouchWindow,系统就会不再发送WM_GESTURE,而把底层的WM_TOUCH发给应用程序。WM_GESTURE虽然简单,但缺点很明显。它受限于支持的几种手势,没有办法添加自定义的。所以这里只打算介绍WM_TOUCH,以及如何自己完成手势识别。

WM_TOUCH就是个简单直接的消息,没有WM_TOUCHDOWN、WM_TOUCH_UP、WM_TOUCHMOVE这些。WM_TOUCH会把当前所有触点的坐标、ID、标志、发送设备、时间戳等一股脑发送出来,应用程序自己处理up/down/move等。实际上使用起来不困难,MSDN里有很详细的解释,照着它提供的例子来很容易就能完成。尤其的是,触点的标志包含丰富的信息,除了常见的up/down之外,还会标记出这个触点是不是手掌、是否隔空扫过之类。

为了跨平台,KlayGE的touch支持做了一个抽象,每个触点就保留坐标、ID、是否按下三个信息。

手势识别

前面提到了不用WM_GESTURE的原因是不能自定义手势,代价就是需要自己写手势识别了。事实证明,那件事情其实很容易,只要一个状态机就全部搞定。目前支持的手势有,pan、tap、press、press and tap、zoom、rotate、flick。通过对状态机的扩展,要加入新的手势不难。同时,遵循着KlayGE输入系统的抽象原则,这里仍然是插件层负责获取底层的触点信息,核心层负责做手势识别。这样不管是Win7、Win8还是Android,识别部分是完全相同的。

目前的状态机是这样的:

Gesture state machine

 

Win7的touch底层API设计比较像Raw input,而高层API又限制太大了,两者之间没有任何过渡层可以使用。下一篇我们来看看Win8的Pointer API,包括Desktop和Metro的,以及Android的motion event。