Kinect開発備忘録(3) ハンドカーソルを扱ってみる

仮想デスクトップ搭載との噂のWindows9やとても今HotなOculus Riftについて語りたい今日この頃ですが、今回もKinect開発についての情報を書き綴っていきます。なんといってもKinectは情報がなかなか無いので、このブログを通して他の開発者の皆さんのお役にたてればと思っています。(Windows9やOculus Riftについてはこのブログを訪れなくても情報を得れると思いますので……。)

さて、今回はハンドカーソルの制御について記載していきます。なぜ、ハンドカーソルかと言いますと、思わぬところで、はまってしまったんで……。(尚、今回もSDKは1.8で話を進めています)

 

まず、ハンドカーソルの使い方なんですがMicrosoft.Kinect.Toolkit.Controls.KinectRegionクラスを使用します。
KinectRegionですが画面に埋め込むとハンドカーソルが表示され、指定した領域内でハンドカーソルが有効となります
このあたりの動きについてはサンプルのControlsBasicsアプリを確認して頂くと良いかと思います。

ハンドカーソルの制御はKinectRegionクラス内で行っていますので、KinectRegionのメソッドを通してハンドカーソルを扱います

MSDNを確認すると、幾つかのイベントに対応しています。

KinectRegion Methods

使い方自体は簡単です。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についても相変わらず情報がネットにも転がっていないので、備忘録を記載したい所ですがそれは次の機会とします。

20140717画像引用:Microsoft

木曜日担当 Window開発チーム 古村



アプリ関連ニュース

お問い合わせはこちら

お問い合わせ・ご相談はお電話、またはお問い合わせフォームよりお受け付けいたしております。

tel. 06-6454-8833(平日 10:00~17:00)

お問い合わせフォーム