Kinect連動デジタルサイネージ KineticSignage

ソースコード
VC++にて実装された、Kinect、Direct2D、WinSock2.2を利用したサーバ・クライアント型デジタルサイネージ
腕の動きによってスライド写真を切り替えるサンプル・デモです。

+--------+          +--------------+
| Kinect | ==USB==> + KinectServer |
+--------+          +--------------+
                           //
                           \\ UDP
                           // Broadcast
                          \ /
                   +----------------+
 Display <======== + KineticSignage |
                   +----------------+

## KinectServer
### 仕様と注意
骨格情報をUDPポート65487番で同一ネットワーク内にブロードキャストします。

UDPはTCPのようにシーケンス番号やACKがないため、クライアント側では、時系列でのパケット欠損、時系列の前後に気づくことはできません。
そのため、当プログラムは小規模かつ安定的なローカルネットワークにおける運用を想定しています。
実装されているコードではブロードキャストするため、ルータによってセグメントが分割されたネットワークでの運用を推奨します。
(多くの場合、ルータはUDPブロードキャストパケットを破棄します)

### プロトコルは以下:

    [
      [
        [float x, float y, float z, float w]...
      ]...
    ]...

#### skeleton position
x,y,z,wはfloatの座標データ、この固定長の配列は骨格座標です。

cf. struct Vector4, NuiSensor.h, Kinect SDK

#### skeleton positions = human
骨格座標は複数含められます。これはNuiSensor.hで列挙されているNUI_SKELETON_POSITION_*のインデックスと同じインデックスが振られています

cf. enum NUI_SKELETON_POSITION_INDEX, NuiSensor.h, Kinect SDK

#### humans
skeleton positions (つまりhuman)の配列としてのhumans

cf. struct NUI_SKELETON_FRAME.SkeletonData

この配列コンテナはMessagePackのシリアライザによってシリアライズされ、ひとつのUDPデータグラムしてブロードキャストされます。
UDPペイロードはこの一種類だけです。ペイロードをMessagePackでデシリアライズすれば、どのような環境でも上記配列が展開されます。
これにより、一台のKinectから発せられるデータを複数機器で共有可能。

## KineticSignage
### 概要
サーバから送られるパケットを見て描画するデジタルサイネージクライアント。あまりメモリは不要。Direct2DなのでWindows 7が必須。
同期的(blocking)な受信部分と描画部でスレッドを分けています。グローバル変数で角度値を共有。
描画はDirect2D。ハードコードされたディレクトリの写真をすべて読みに行きます。

右手が右ひじより上にあるもしくは左手が左ひじより上にある場合、
角度=arctan(手首y-ひじy,手首x-ひじx)
(右手優先)

角度をもとに、写真を切り替えていきます。