Kinect開発備忘録(3) ハンドカーソルを扱ってみる
- 2014年8月15日
- Kinect
仮想デスクトップ搭載との噂のWindows9やとても今HotなOculus Riftについて語りたい今日この頃ですが、今回もKinect開発についての情報を書き綴っていきます。なんといってもKinectは情報がなかなか無いので、このブログを通して他の開発者の皆さんのお役にたてればと思っています。(Windows9やOculus Riftについてはこのブログを訪れなくても情報を得れると思いますので……。)
さて、今回はハンドカーソルの制御について記載していきます。なぜ、ハンドカーソルかと言いますと、思わぬところで、はまってしまったんで……。(尚、今回もSDKは1.8で話を進めています)
まず、ハンドカーソルの使い方なんですがMicrosoft.Kinect.Toolkit.Controls.KinectRegionクラスを使用します。
KinectRegionですが画面に埋め込むとハンドカーソルが表示され、指定した領域内でハンドカーソルが有効となります。
このあたりの動きについてはサンプルのControlsBasicsアプリを確認して頂くと良いかと思います。
ハンドカーソルの制御はKinectRegionクラス内で行っていますので、KinectRegionのメソッドを通してハンドカーソルを扱います。
MSDNを確認すると、幾つかのイベントに対応しています。
使い方自体は簡単です。KinectRegionクラスに、ハンドカーソルのイベントと、対象のコントロールを登録するだけ。
例えば、imageという画像コントロールに対し、押す又は押して手を戻した場合に何か処理を行いたいなら以下のようなコードを記載すればOKです。
(尚、この時使用するKinectRegionは、インスタンスでは無くstaticなので使用の際はご注意を)
// 押す動作
KinectRegion.AddHandPointerPressHandler(this.image, OnHandPointerPress);
// 押して手を元に戻した場合の動作
KinectRegion.AddHandPointerPressReleaseHandler(this.image, OnHandPointerPressRelease);
// 登録したコントロールに対し、ハンドカーソルで押した場合呼ばれる
private void OnHandPointerPress(object sender, HandPointerEventArgs e)
{
// 押す動作をした場合の処理
}
// 登録したコントロールに対し、ハンドカーソルで手を元に戻した場合呼ばれる
private void OnHandPointerPressRelease(object sender, HandPointerEventArgs e)
{
// 手を元に戻した場合の処理
}
他にも手を握った際のイベントのAddHandPointerGripHandlerや、コントロールの上を移動中のイベントAddHandPointerMoveHandler等があるので、用途に応じて使い分けてもらえればと思います。
さて、このハンドカーソルですが手を開いたり、握ったりした場合にControlsBasicsアプリのようにカーソルの状態も反映したいと考えていました。で、コレが以外と手を焼きました。
前述のAddHandPointerGripHandlerではイベントは取得出来ますが、画面上に表示しているカーソルは手を開いたままの状態でした。ControlsBasicsアプリのソースを参考にしたり、AddHandPointer……のイベントを全て駆使してみたのですが、握った瞬間はハンドカーソルも握った表示になるのですが、その状態を保持する事が出来ませんでした。
色々と調べてみた結果、AddHandPointer……では無く、HandPointersUpdatedを使用すれば実現出来る事がわかりました。
ソースコードはこんな感じです。
this.kinectRegion.HandPointersUpdated += this.OnHandPointersUpdated;
private void OnHandPointersUpdated(object sender, EventArgs args)
{
foreach (HandPointer pointer in this.kinectRegion.HandPointers)
{
// 有効なユーザー、現在しようしている手以外の場合は処理を行わない
if (!pointer.IsPrimaryUser || !pointer.IsPrimaryHandOfUser)
{
continue;
}
pointer.IsInGripInteraction = this.isGrip;
}
}
たかがこのコードを書くためにKinect.Toolkit.Controlsを解析した為、かなり時間を費やしてしまいました。
SDK2.0についても相変わらず情報がネットにも転がっていないので、備忘録を記載したい所ですがそれは次の機会とします。
木曜日担当 Window開発チーム 古村
komu at 2014年08月15日 10:00:19