これも Kinect for Windows SDK にあって、OpenNIになかった機能です。
実行中にデバイスが刺されたり、抜かれたりを検出できるようになりました。ビジネスアプリケーションとして、使う場合、この機能はほぼ必須なのでありがたいです。
#include <Windows.h>#include <conio.h>
#include <iostream>
#include <OpenNI.h>
class DeviceStatusListener : public openni::OpenNI::Listener
{
public:
DeviceStatusListener()
{
}
virtual void onDeviceStateChanged( const openni::DeviceInfo* device,
openni::DeviceState state )
{
std::cout << "onDeviceStateChanged(" << ::GetCurrentThreadId() << ") : "
<< device->getName() << " : " << state << std::endl;
}
virtual void onDeviceConnected( const openni::DeviceInfo* device )
{
std::cout << "onDeviceConnected(" << ::GetCurrentThreadId() << ") : "
<< device->getName() << std::endl;
}
virtual void onDeviceDisconnected( const openni::DeviceInfo* device )
{
std::cout << "onDeviceDisconnected(" << ::GetCurrentThreadId() << ") : "
<< device->getName() << std::endl;
}
};
void main()
{
try {
std::cout << "main(" << ::GetCurrentThreadId() << ")" << std::endl;
openni::OpenNI::initialize();
DeviceStatusListener listener;
openni::OpenNI::addListener( &listener );
while ( _kbhit() == 0 ) {
::Sleep( 1 );
}
}
catch ( std::exception& ) {
std::cout << openni::OpenNI::getExtendedError() << std::endl;
}
}
これを実行すると、Kinect,Xtionそれぞれの挿抜を検出できます。
いくつかポイントになりそうな箇所を記録しておきます。
挿抜認識は別スレッド
main()と各デバイスの挿抜認識は別スレッドになるようです。このため、メインループ実行中に挿抜認識が確実に行えるようにする必要がありそうです。
Kinectの接続認識はConnected→StateChanged
Kinect for Windows SDKから取得しているため、認識もSDKに倣っているようです。ConnectedのあとにStateChangedが2回(おそらくInitializeとConnected)呼ばれるので、実際に接続処理を行うのは2回目のStateChangedになりそうですね。