11#ifdef ENABLE_KINECT_SDK
16CKinectWin::CKinectWin(
void)
21#ifdef ENABLE_NI_SPEECH
31 m_is_detected = FALSE;
32 m_is_tracking = FALSE;
33 m_is_mirroring = TRUE;
42 m_enable_face = FALSE;
43 m_enable_speech = FALSE;
44 m_enable_motor = TRUE;
46 m_use_knct_smth = TRUE;
48 m_profile = KINECT_SKEL_PROFILE_ALL;
55 isDetectShadow = FALSE;
62 smoothParam.fSmoothing = 0.5f;
63 smoothParam.fCorrection = 0.5f;
64 smoothParam.fPrediction = 0.5f;
65 smoothParam.fJitterRadius = 0.05f;
66 smoothParam.fMaxDeviationRadius = 0.04f;
68 clearAvatarDetected();
73CKinectWin::~CKinectWin(
void)
75 DEBUG_INFO(
"DESTRUCTOR: CKinectWin: START\n");
77 DEBUG_INFO(
"DESTRUCTOR: CKinectWin: END\n");
82BOOL CKinectWin::init(
void)
84 device =
new CKinectDevice();
87 ::NuiSetDeviceStatusCallback((NuiStatusProc)&KinectStatusProc,
this);
90 DWORD mode = NUI_INITIALIZE_FLAG_USES_COLOR |
91 NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX |
92 NUI_INITIALIZE_FLAG_USES_SKELETON |
93 NUI_INITIALIZE_FLAG_USES_AUDIO;
95 BOOL ret = device->init(mode, m_use_image);
97 m_err_mesg = device->m_err_mesg;
101 setDevState(NI_STATE_DETECT_STOPPED);
108void CKinectWin::free(
void)
118void CKinectWin::deleteDevice(
void)
120 DEBUG_INFO(
"CKinectWin::deleteDevice(): START\n");
124 DEBUG_INFO(
"CKinectWin::deleteDevice(): END\n");
131CString CKinectWin::get_err_message(
void)
133 DEBUG_INFO(
"CKinectWin::get_err_message(): => %s\n", ::ts2mbs(m_err_mesg));
134 CString mesg = m_err_mesg;
142void CKinectWin::clearJointsData(
void)
144 for (
int i=0; i<KINECT_JOINT_NUM; i++) {
145 rotQuat[i].init(-1.0);
146 posVect[i].init(-1.0);
153BOOL CKinectWin::initRingBuffer(
void)
157 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
160 if (posRing[j].state<0 || rotRing[j].state<0) {
162 m_err_mesg = _T(
"CKinectWin::initRingBuffer(): WARNING: Out of Memory.");
173void CKinectWin::freeRingBuffer(
void)
175 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
176 if (posRing[j].enable) posRing[j].free();
177 if (rotRing[j].enable) rotRing[j].free();
183void CKinectWin::clearRingBuffer(
void)
185 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
186 if (posRing[j].enable) posRing[j].clear();
187 if (rotRing[j].enable) rotRing[j].clear();
193void CKinectWin::backup2RingBuffer(
void)
195 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
196 if (posVect[j].c>=m_confidence) posRing[j].put(&posVect[j]);
197 if (rotQuat[j].c>=m_confidence) rotRing[j].put(&rotQuat[j]);
207void CKinectWin::clearAvatarDetected(
void)
212 startPos = Vector<float>(0.0, 0.0, 0.0);
213 currentPos = Vector<float>(0.0, 0.0, 0.0);
214 m_is_detected = FALSE;
222BOOL CKinectWin::checkAvatarDetected(
void)
226 m_is_detected = TRUE;
232 m_ground_level = Min(m_ground_level, posVect[
NI_SDK_L_ANKLE].z - startPos.z);
240 return m_is_detected;
245void CKinectWin::setTiltMotor(
int ang)
247 if (m_use_motor && m_enable_motor) {
248 m_enable_motor = FALSE;
249 NuiCameraElevationSetAngle(ang);
251 m_enable_motor = TRUE;
257void CKinectWin::setMirroring(BOOL mirror)
259 m_is_mirroring = mirror;
264BOOL CKinectWin::startDetection(
void)
268 device->smoothParam = NULL;
269 if (m_use_knct_smth) device->smoothParam = &smoothParam;
273 BOOL ret = device->start_Detection(m_profile);
274 if (ret) setLEDColor(NI_LED_BLINK_ORANGE);
275 else m_err_mesg = device->m_err_mesg;
278 if (ret && m_use_face) {
279 ret = device->create_Face();
280 if (!ret) m_err_mesg = device->m_err_mesg;
288BOOL CKinectWin::stopDetection(
void)
290 BOOL ret = device->stop_Detection();
291 if (!ret) m_err_mesg = device->m_err_mesg;
292 setLEDColor(NI_LED_GREEN);
298 isDetectFace = FALSE;
299 device->delete_Face();
306BOOL CKinectWin::restartDetection(
void)
308 BOOL ret = stopDetection();
309 if (ret) ret = startDetection();
316Vector4 CKinectWin::jointPositionData(
int j)
320 if (j>=0 && j<KINECT_JOINT_NUM) {
321 vect = device->jointPosData[j];
324 memset(&vect, 0,
sizeof(Vector4));
335void CKinectWin::makeDisplayImage()
341 if (pViewData==NULL)
return;
343 if (device->image!=NULL && m_use_image) {
344 src = (uByte*)device->image->m_data;
349 for (
int j=0; j<pViewData->ysize; j++) {
351 int ls = j*m_image_scale*device->m_xsize;
353 for (
int i=0; i<pViewData->xsize; i++) {
355 if (m_is_mirroring) li = i*m_image_scale;
356 else li = (pViewData->xsize-i-1)*m_image_scale;
358 ptr = &(pViewData->point(i, j));
361 ptr[1] = src[index+1];
362 ptr[2] = src[index+2];
363 ptr[3] = src[index+3];
370 for (
int j=0; j<pViewData->ysize; j++) {
372 int ls = j*m_image_scale*device->m_xsize;
374 for (
int i=0; i<pViewData->xsize; i++) {
376 if (m_is_mirroring) li = i*m_image_scale;
377 else li = (pViewData->xsize-i-1)*m_image_scale;
379 ptr = &(pViewData->point(i, j));
380 ptr[0] = ptr[1] = ptr[2] = 224;
392void CKinectWin::makeDisplayDepth(
CExView* pview)
394 if (pview==NULL)
return;
398 if (device->depth!=NULL && hasDepthData) {
399 src = (uWord*)device->depth->m_data;
401 if (src==NULL)
return;
404 uWord max = pview->
cMax;
405 uWord min = pview->
cMin;
407 uWord* wrk = (uWord*)malloc(
sizeof(uWord)*pDepthData->ysize*pDepthData->xsize);
410 for (
int j=0; j<pDepthData->ysize; j++) {
411 int jj = j*pDepthData->xsize;
412 int ls = j*m_depth_scale*device->m_xsize;
414 for (
int i=0; i<pDepthData->xsize; i++) {
416 int li = i*m_depth_scale;
417 if (!m_is_mirroring) li = device->m_xsize - li - 1;
420 wrk[k] = ::NuiDepthPixelToDepth(src[ls+li]);
421 if (wrk[k]>max) wrk[k] = max;
422 else if (wrk[k]<min) wrk[k] = min;
427 float dif = (float)(max - min);
428 uByte* ptr = (uByte*)pDepthData->grptr;
431 for (
int i=0; i<pDepthData->ysize*pDepthData->xsize; i++) {
432 ptr[i] = (uByte)((max - wrk[i])/dif*255);
436 for (
int i=0; i<pDepthData->ysize*pDepthData->xsize; i++) {
437 ptr[i] = (uByte)(255 - wrk[i]/256);
451BOOL CKinectWin::trackingJoints(
void)
453 m_is_tracking = FALSE;
458 int tuser = tracking_user;
459 tracking_user = device->wait_Skeleton(tracking_user, tracking_deny);
461 if (tuser!=tracking_user) {
462 m_is_detected = FALSE;
463 if (tracking_user==0) {
464 clearAvatarDetected();
465 lostTrackingUser(tuser);
469 detectTrackingUser(tracking_user);
474 if (tracking_user>0 && tracking_user<=KINECT_USERS_NUM) {
492 m_is_tracking = TRUE;
496 m_is_detected = FALSE;
499 return m_is_tracking;
504Vector4 CKinectWin::joint_PositionData(
int j)
508 if (j>=0 && j<KINECT_JOINT_NUM) {
509 vect = device->jointPosData[j];
512 memset(&vect, 0,
sizeof(Vector4));
522void CKinectWin::getJointsPosData(
void)
524 if (!m_is_mirroring) {
525 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
526 device->jointPosData[j].x = - device->jointPosData[j].x;
531 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
532 Vector4 pos = device->jointPosData[j];
535 posVect[n].set(-pos.z, pos.x, pos.y);
539 if (m_profile==KINECT_SKEL_PROFILE_ALL) {
544 else if (m_profile==KINECT_SKEL_PROFILE_UPPER) {
556 Vector<float> torso_down(0.0f, 0.0f, -0.2f);
566 if (!m_is_detected) checkAvatarDetected();
570 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
571 posVect[j] = posVect[j] - startPos;
572 if (posVect[j].c<m_confidence || crdVect[j].c<0.0) posVect[j].c = -1.0;
583BOOL CKinectWin::detectShadow(
void)
587 if (pViewData==NULL)
return FALSE;
590 for (
int j=0; j<pViewData->ysize; j++) {
592 int lj = j*m_image_scale;
594 for (
int i=0; i<pViewData->xsize; i++) {
596 if (m_is_mirroring) li = i*m_image_scale;
597 else li = (pViewData->xsize-i-1)*m_image_scale;
600 if (getDevState()==NI_STATE_DETECT_EXEC && hasDepthData) {
602 label = device->depth->get_user_index(li, lj);
604 if (tracking_user==label)
return TRUE;
615void CKinectWin::paintShadow(
void)
620 if (pViewData==NULL)
return;
622 if (getDevState()==NI_STATE_DETECT_EXEC && hasDepthData) {
624 for (
int j=0; j<pViewData->ysize; j++) {
626 int lj = j*m_image_scale;
628 for (
int i=0; i<pViewData->xsize; i++) {
630 if (m_is_mirroring) li = i*m_image_scale;
631 else li = (pViewData->xsize-i-1)*m_image_scale;
634 label = device->depth->get_user_index(li, lj);
636 ptr = &(pViewData->point(i, j));
646void CKinectWin::drawSkeleton(
int col,
int line)
675void CKinectWin::drawJointConnection(
int j1,
int j2,
int col,
int line)
677 if (pViewData==NULL)
return;
679 MSGraph<unsigned int> vp;
680 vp.xs = pViewData->xsize;
681 vp.ys = pViewData->ysize;
683 vp.gp = (
unsigned int*)pViewData->grptr;
685 if (crdVect[j1].c>0.0 && crdVect[j2].c>0.0) {
686 MSGraph_Line(vp, crdVect[j1].x, crdVect[j1].y, crdVect[j2].x, crdVect[j2].y, col);
687 for (
int i=1; i<line; i++) {
688 MSGraph_Line(vp, crdVect[j1].x+i, crdVect[j1].y, crdVect[j2].x+i, crdVect[j2].y, col);
689 MSGraph_Line(vp, crdVect[j1].x-i, crdVect[j1].y, crdVect[j2].x-i, crdVect[j2].y, col);
690 MSGraph_Line(vp, crdVect[j1].x, crdVect[j1].y+i, crdVect[j2].x, crdVect[j2].y+i, col);
691 MSGraph_Line(vp, crdVect[j1].x, crdVect[j1].y-i, crdVect[j2].x, crdVect[j2].y-i, col);
698void CKinectWin::set2DCoordinate(
void)
700 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
701 crdVect[j].init(-1.0);
705 if (device->depth!=NULL && pViewData!=NULL) {
707 for (
int j=0; j<KINECT_JOINT_NUM; j++) {
711 if (m_profile==KINECT_SKEL_PROFILE_UPPER) {
712 Vector4 pos_neck = device->jointPosData[
NI_SDK_NECK];
716 pos.x = (FLOAT)((pos_rshd.x + pos_lshd.x)*1.5 - pos_neck.x*2.0);
717 pos.y = (FLOAT)((pos_rshd.y + pos_lshd.y)*1.5 - pos_neck.y*2.0);
718 pos.z = (FLOAT)((pos_rshd.z + pos_lshd.z)*1.5 - pos_neck.z*2.0);
726 pos.x = (FLOAT)(pos_pelv.x*2.0 -(pos_rhip.x+pos_lhip.x)*0.5);
727 pos.y = (FLOAT)(pos_pelv.y*2.0 -(pos_rhip.y+pos_lhip.y)*0.5);
728 pos.z = (FLOAT)(pos_pelv.z*2.0 -(pos_rhip.z+pos_lhip.z)*0.5);
732 pos = device->jointPosData[j];
736 pos = device->jointPosData[j];
740 NuiTransformSkeletonToDepthImage(pos, &x, &y, NUI_IMAGE_RESOLUTION_640x480);
745 device->depth->get_image_coord(&xs, &ys);
746 if (xs>=0) xs = xs/m_image_scale;
747 if (ys>=0) ys = ys/m_image_scale;
751 if (xs>0 && xs<pViewData->xsize && ys>0 && ys<pViewData->ysize) {
767#ifdef ENABLE_NI_SPEECH
769BOOL CKinectWin::initSpeech(
void)
773 if (audio==NULL) audio =
new CKinectAudio();
775 BOOL ret = audio->init(device->context, KINECT_AUDIO_SINGLE_AEC);
776 if (!ret) m_err_mesg = _T(
"CKinectWin::initSpeech(): ERROR: Audio Initialization Error!!");
780 if (speech==NULL) speech = makeSpeech();
781 WAVEFORMATEX format = audio->getAudioFormat();
782 IStream* stream = audio->getIStream();
783 ret = speech->init(stream, &format);
784 if (!ret) m_err_mesg = _T(
"CKinectWin::initSpeech(): ERROR: Speech Initialization Error!!");
802BOOL CKinectWin::createSpeech(LPCTSTR lang, LPCTSTR grfile)
807 if (speech==NULL) ret = initSpeech();
810 ret = speech->create(lang);
811 if (!ret) m_err_mesg = _T(
"CKinectWin::createSpeech(): ERROR: Speech Context Creation Error!!\nPerhaps, Language Pack is not installed.");
815 ret = speech->load(grfile);
817 m_err_mesg = _T(
"CKinectWin::createSpeech(): ERROR: Grammar File Loading Error!!\nFile = ");
818 m_err_mesg += grfile;
823 if (!ret)
return FALSE;
829BOOL CKinectWin::startSpeech(
float confidence)
833 if (audio==NULL || speech==NULL) {
834 m_err_mesg = _T(
"CKinectWin::startSpeech(): ERROR: Audio or Speech Instance is/are NULL!!");
838 BOOL ret = audio->startCapture();
839 if (!ret) m_err_mesg = _T(
"CKinectWin::startSpeech(): ERROR: Audio Capture Starting Error!!");
842 ret = speech->start(confidence);
844 audio->stopCapture();
845 m_err_mesg = _T(
"CKinectWin::startSpeech(): ERROR: Speech Platform Starting Error!!");
850 if (m_err_mesg==_T(
"")) m_err_mesg = _T(
"CKinectWin::startSpeech(): ERROR: Unknown Error!!");
859void CKinectWin::stopSpeech(
void)
866 audio->stopCapture();
874void CKinectWin::deleteSpeech(BOOL rls)
876 DEBUG_INFO(
"CKinectWin::deleteSpeech(): START\n");
882 if (rls) speech->free();
890 DEBUG_INFO(
"CKinectWin::deleteSpeech(): END\n");
901Quaternion<float> CKinectWin::getFaceRotation(
void)
903 Quaternion<float> quat(1.0, 0.0, 0.0, 0.0, 1.0);
905 Vector<float> eulr = device->face->getFaceEulerXYZ();
907 if (m_is_mirroring) {
908 vect.set(-eulr.x, -eulr.y, eulr.z);
911 vect.set(-eulr.x, eulr.y, -eulr.z);
914 quat.setEulerYZX(vect);
925void CKinectWin::callback_status_changed(BOOL success,
const OLECHAR* instanceName,
const OLECHAR* deviceName)
928 DEBUG_INFO(
"CKinectWin:::called_change_status(): SUCCEEDED: %s %s\n", (
char*)instanceName, (
char*)deviceName);
932 DEBUG_INFO(
"CKinectWin::called_change_status(): ERROR: %s %s\n", (
char*)instanceName, (
char*)deviceName);
943void CALLBACK jbxwl::KinectStatusProc(HRESULT hr,
const OLECHAR* instanceName,
const OLECHAR* deviceName,
void* pUserData)
945 CKinectWin* kinect = (CKinectWin*)pUserData;
948 if (kinect!=NULL) kinect->callback_status_changed(TRUE, instanceName, deviceName);
951 if (kinect!=NULL) kinect->callback_status_changed(FALSE, instanceName, deviceName);
void NiSetUserColor(int label, uByte *ptr, BOOL use_image=TRUE)
int NiSDKMirrorJointNum(int joint, NiSDK_Lib lib)
unsigned int NiGetSkeletonColor(int label)