![]() |
NiTE 2.0
|
00001 /******************************************************************************* 00002 * * 00003 * PrimeSense NiTE 2.0 * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 *******************************************************************************/ 00007 00008 #ifndef _NITE_H_ 00009 #define _NITE_H_ 00010 00011 #include "NiteCAPI.h" 00012 #include <OpenNI.h> 00013 00014 // Summary of use cases, modules, facades 00015 00016 namespace nite { 00017 #include "NiteEnums.h" 00018 00019 // General 00020 _NITE_DECLARE_VERSION(Version); 00021 00022 class Point3f : public NitePoint3f 00023 { 00024 public: 00025 Point3f() 00026 { 00027 x = y = z = 0.0f; 00028 } 00029 Point3f(float x, float y, float z) 00030 { 00031 this->set(x, y, z); 00032 } 00033 Point3f(const Point3f& other) 00034 { 00035 *this = other; 00036 } 00037 00038 void set(float x, float y, float z) 00039 { 00040 this->x = x; 00041 this->y = y; 00042 this->z = z; 00043 } 00044 00045 Point3f& operator=(const Point3f& other) 00046 { 00047 set(other.x, other.y, other.z); 00048 00049 return *this; 00050 } 00051 bool operator==(const Point3f& other) const 00052 { 00053 return x == other.x && y == other.y && z == other.z; 00054 } 00055 bool operator!=(const Point3f& other) const 00056 { 00057 return !operator==(other); 00058 } 00059 }; 00060 00061 class Plane : public NitePlane 00062 { 00063 public: 00064 Plane() 00065 { 00066 this->point = Point3f(); 00067 this->normal = Point3f(); 00068 } 00069 Plane(const Point3f& point, const Point3f& normal) 00070 { 00071 this->point = point; 00072 this->normal = normal; 00073 } 00074 }; 00075 class Quaternion : public NiteQuaternion 00076 { 00077 public: 00078 Quaternion() 00079 { 00080 x = y = z = w = 0; 00081 } 00082 Quaternion(float w, float x, float y, float z) 00083 { 00084 this->x = x; 00085 this->y = y; 00086 this->z = z; 00087 this->w = w; 00088 } 00089 }; 00090 00091 class BoundingBox : public NiteBoundingBox 00092 { 00093 public: 00094 BoundingBox(); 00095 BoundingBox(const Point3f& min, const Point3f& max) 00096 { 00097 this->min = min; 00098 this->max = max; 00099 } 00100 }; 00101 00107 template <class T> 00108 class Array 00109 { 00110 public: 00114 Array() : m_size(0), m_data(NULL) {} 00122 void setData(int size, T* data) {m_data = data; m_size = size;} 00126 const T& operator[](int index) const {return m_data[index];} 00131 int getSize() const {return m_size;} 00136 bool isEmpty() const {return m_size == 0;} 00137 private: 00138 Array(const Array&); 00139 Array& operator=(const Array&); 00140 00141 int m_size; 00142 T* m_data; 00143 }; 00144 00145 // UserTracker 00150 typedef short int UserId; 00151 00155 class PoseData : protected NitePoseData 00156 { 00157 public: 00161 PoseType getType() const {return (PoseType)type;} 00162 00166 bool isHeld() const {return (state & NITE_POSE_STATE_IN_POSE) != 0;} 00170 bool isEntered() const {return (state & NITE_POSE_STATE_ENTER) != 0;} 00174 bool isExited() const {return (state & NITE_POSE_STATE_EXIT) != 0;} 00175 }; 00176 00182 class UserMap : private NiteUserMap 00183 { 00184 public: 00188 const UserId* getPixels() const {return pixels;} 00192 int getWidth() const {return width;} 00196 int getHeight() const {return height;} 00200 int getStride() const {return stride;} 00201 00202 friend class UserTrackerFrameRef; 00203 }; 00204 00208 class SkeletonJoint : private NiteSkeletonJoint 00209 { 00210 public: 00214 JointType getType() const {return (JointType)jointType;} 00218 const Point3f& getPosition() const {return (Point3f&)position;} 00222 float getPositionConfidence() const {return positionConfidence;} 00226 const Quaternion& getOrientation() const {return (Quaternion&)orientation;} 00230 float getOrientationConfidence() const {return orientationConfidence;} 00231 }; 00235 class Skeleton : private NiteSkeleton 00236 { 00237 public: 00241 const SkeletonJoint& getJoint(JointType type) const {return (SkeletonJoint&)joints[type];} 00245 SkeletonState getState() const {return (SkeletonState)state;} 00246 }; 00250 class UserData : private NiteUserData 00251 { 00252 public: 00256 UserId getId() const {return id;} 00260 const BoundingBox& getBoundingBox() const {return (const BoundingBox&)boundingBox;} 00264 const Point3f& getCenterOfMass() const {return (const Point3f&)centerOfMass;} 00268 bool isNew() const {return (state & NITE_USER_STATE_NEW) != 0;} 00272 bool isVisible() const {return (state & NITE_USER_STATE_VISIBLE) != 0;} 00277 bool isLost() const {return (state & NITE_USER_STATE_LOST) != 0;} 00278 00282 const Skeleton& getSkeleton() const {return (const Skeleton&)skeleton;} 00283 00287 const PoseData& getPose(PoseType type) const {return (const PoseData&)poses[type];} 00288 }; 00289 00291 class UserTrackerFrameRef 00292 { 00293 public: 00294 UserTrackerFrameRef() : m_pFrame(NULL), m_userTrackerHandle(NULL) 00295 {} 00296 ~UserTrackerFrameRef() 00297 { 00298 release(); 00299 } 00300 00301 UserTrackerFrameRef(const UserTrackerFrameRef& other) : m_pFrame(NULL) 00302 { 00303 *this = other; 00304 } 00305 UserTrackerFrameRef& operator=(const UserTrackerFrameRef& other) 00306 { 00307 setReference(other.m_userTrackerHandle, other.m_pFrame); 00308 niteUserTrackerFrameAddRef(m_userTrackerHandle, m_pFrame); 00309 00310 return *this; 00311 } 00312 00313 bool isValid() const 00314 { 00315 return m_pFrame != NULL; 00316 } 00317 00318 void release() 00319 { 00320 if (m_pFrame != NULL) 00321 { 00322 niteUserTrackerFrameRelease(m_userTrackerHandle, m_pFrame); 00323 } 00324 m_pFrame = NULL; 00325 m_userTrackerHandle = NULL; 00326 } 00327 00328 const UserData* getUserById(UserId id) const 00329 { 00330 for (int i = 0; i < m_users.getSize(); ++i) 00331 { 00332 if (m_users[i].getId() == id) 00333 { 00334 return &m_users[i]; 00335 } 00336 } 00337 return NULL; 00338 } 00339 00343 const Array<UserData>& getUsers() const {return m_users;} 00344 00348 float getFloorConfidence() const {return m_pFrame->floorConfidence;} 00352 const Plane& getFloor() const {return (const Plane&)m_pFrame->floor;} 00353 00357 openni::VideoFrameRef getDepthFrame() {return m_depthFrame;} 00361 const UserMap& getUserMap() const {return static_cast<const UserMap&>(m_pFrame->userMap);} 00366 uint64_t getTimestamp() const {return m_pFrame->timestamp;} 00367 00368 int getFrameIndex() const {return m_pFrame->frameIndex;} 00369 private: 00370 friend class User; 00371 friend class UserTracker; 00372 00373 Array<UserData> m_users; 00374 00375 void setReference(NiteUserTrackerHandle userTrackerHandle, NiteUserTrackerFrame* pFrame) 00376 { 00377 release(); 00378 m_userTrackerHandle = userTrackerHandle; 00379 m_pFrame = pFrame; 00380 m_depthFrame._setFrame(pFrame->pDepthFrame); 00381 m_users.setData(m_pFrame->userCount, (UserData*)m_pFrame->pUser); 00382 00383 } 00384 00385 NiteUserTrackerFrame* m_pFrame; 00386 NiteUserTrackerHandle m_userTrackerHandle; 00387 openni::VideoFrameRef m_depthFrame; 00388 }; 00389 00394 class UserTracker 00395 { 00396 public: 00397 class Listener 00398 { 00399 public: 00400 Listener() : m_pUserTracker(NULL) 00401 { 00402 m_userTrackerCallbacks.readyForNextFrame = newFrameCallback; 00403 } 00404 00405 // SAme name as in OPenNI. Not abstract - make sure OPenNI is the same 00406 virtual void onNewFrame(UserTracker&) {} 00407 00408 private: 00409 NiteUserTrackerCallbacks m_userTrackerCallbacks; 00410 00411 NiteUserTrackerCallbacks& getCallbacks() {return m_userTrackerCallbacks;} 00412 00413 static void ONI_CALLBACK_TYPE newFrameCallback(void* pCookie) 00414 { 00415 Listener* pListener = (Listener*)pCookie; 00416 pListener->onNewFrame(*pListener->m_pUserTracker); 00417 } 00418 00419 00420 friend class UserTracker; 00421 void setUserTracker(UserTracker* pUserTracker) 00422 { 00423 m_pUserTracker = pUserTracker; 00424 } 00425 00426 UserTracker* m_pUserTracker; 00427 }; 00428 00429 UserTracker() : m_userTrackerHandle(NULL) 00430 {} 00431 00432 00433 ~UserTracker() 00434 { 00435 destroy(); 00436 } 00437 00438 Status create(openni::Device* pDevice = NULL) 00439 { 00440 if (pDevice == NULL) 00441 { 00442 return (Status)niteInitializeUserTracker(&m_userTrackerHandle); 00443 } 00444 return (Status)niteInitializeUserTrackerByDevice(pDevice, &m_userTrackerHandle); 00445 } 00446 00447 void destroy() 00448 { 00449 if (isValid()) 00450 { 00451 niteShutdownUserTracker(m_userTrackerHandle); 00452 m_userTrackerHandle = NULL; 00453 } 00454 } 00455 00457 Status readFrame(UserTrackerFrameRef* pFrame) 00458 { 00459 NiteUserTrackerFrame *pNiteFrame = NULL; 00460 Status rc = (Status)niteReadUserTrackerFrame(m_userTrackerHandle, &pNiteFrame); 00461 pFrame->setReference(m_userTrackerHandle, pNiteFrame); 00462 00463 return rc; 00464 } 00465 00466 bool isValid() const 00467 { 00468 return m_userTrackerHandle != NULL; 00469 } 00470 00472 Status setSkeletonSmoothingFactor(float factor) 00473 { 00474 return (Status)niteSetSkeletonSmoothing(m_userTrackerHandle, factor); 00475 } 00476 float getSkeletonSmoothingFactor() const 00477 { 00478 float factor; 00479 Status rc = (Status)niteGetSkeletonSmoothing(m_userTrackerHandle, &factor); 00480 if (rc != STATUS_OK) 00481 { 00482 factor = 0; 00483 } 00484 return factor; 00485 } 00486 00488 Status startSkeletonTracking(UserId id) 00489 { 00490 return (Status)niteStartSkeletonTracking(m_userTrackerHandle, id); 00491 } 00493 void stopSkeletonTracking(UserId id) 00494 { 00495 niteStopSkeletonTracking(m_userTrackerHandle, id); 00496 } 00497 00499 Status startPoseDetection(UserId user, PoseType type) 00500 { 00501 return (Status)niteStartPoseDetection(m_userTrackerHandle, (NiteUserId)user, (NitePoseType)type); 00502 } 00503 00505 void stopPoseDetection(UserId user, PoseType type) 00506 { 00507 niteStopPoseDetection(m_userTrackerHandle, (NiteUserId)user, (NitePoseType)type); 00508 } 00509 00510 void addListener(Listener* pListener) 00511 { 00512 niteRegisterUserTrackerCallbacks(m_userTrackerHandle, &pListener->getCallbacks(), pListener); 00513 pListener->setUserTracker(this); 00514 } 00515 void removeListener(Listener* pListener) 00516 { 00517 niteUnregisterUserTrackerCallbacks(m_userTrackerHandle, &pListener->getCallbacks()); 00518 pListener->setUserTracker(NULL); 00519 } 00520 00526 Status convertJointCoordinatesToDepth(float x, float y, float z, float* pOutX, float* pOutY) const 00527 { 00528 return (Status)niteConvertJointCoordinatesToDepth(m_userTrackerHandle, x, y, z, pOutX, pOutY); 00529 } 00535 Status convertDepthCoordinatesToJoint(int x, int y, int z, float* pOutX, float* pOutY) const 00536 { 00537 return (Status)niteConvertDepthCoordinatesToJoint(m_userTrackerHandle, x, y, z, pOutX, pOutY); 00538 } 00539 00540 private: 00541 NiteUserTrackerHandle m_userTrackerHandle; 00542 }; 00543 00544 00545 // HandTracker 00546 typedef short int HandId; 00547 00548 class GestureData : protected NiteGestureData 00549 { 00550 public: 00551 GestureType getType() const {return (GestureType)type;} 00552 const Point3f& getCurrentPosition() const {return (Point3f&)currentPosition;} 00553 00554 bool isComplete() const {return (state & NITE_GESTURE_STATE_COMPLETED) != 0;} 00555 bool isInProgress() const {return (state & NITE_GESTURE_STATE_IN_PROGRESS) != 0;} 00556 }; 00557 00558 class HandData : protected NiteHandData 00559 { 00560 public: 00561 HandId getId() const {return id;} 00562 const Point3f& getPosition() const {return (Point3f&)position;} 00563 00564 bool isNew() const {return (state & NITE_HAND_STATE_NEW) != 0;} 00565 bool isLost() const {return state == NITE_HAND_STATE_LOST;} 00566 bool isTracking() const {return (state & NITE_HAND_STATE_TRACKED) != 0;} 00567 bool isTouchingFov() const {return (state & NITE_HAND_STATE_TOUCHING_FOV) != 0;} 00568 }; 00569 00571 class HandTrackerFrameRef 00572 { 00573 public: 00574 HandTrackerFrameRef() : m_pFrame(NULL), m_handTracker(NULL) 00575 {} 00576 ~HandTrackerFrameRef() 00577 { 00578 release(); 00579 } 00580 00581 HandTrackerFrameRef(const HandTrackerFrameRef& other) : m_pFrame(NULL) 00582 { 00583 *this = other; 00584 } 00585 HandTrackerFrameRef& operator=(const HandTrackerFrameRef& other) 00586 { 00587 setReference(other.m_handTracker, other.m_pFrame); 00588 niteHandTrackerFrameAddRef(m_handTracker, m_pFrame); 00589 00590 return *this; 00591 } 00592 00593 bool isValid() const 00594 { 00595 return m_pFrame != NULL; 00596 } 00597 00598 void release() 00599 { 00600 if (m_pFrame != NULL) 00601 { 00602 niteHandTrackerFrameRelease(m_handTracker, m_pFrame); 00603 } 00604 m_pFrame = NULL; 00605 m_handTracker = NULL; 00606 } 00607 00608 const Array<HandData>& getHands() const {return m_hands;} 00609 const Array<GestureData>& getGestures() const {return m_gestures;} 00610 00611 openni::VideoFrameRef getDepthFrame() const 00612 { 00613 return m_depthFrame; 00614 } 00615 00616 uint64_t getTimestamp() const {return m_pFrame->timestamp;} 00617 int getFrameIndex() const {return m_pFrame->frameIndex;} 00618 private: 00619 friend class HandTracker; 00620 00621 void setReference(NiteHandTrackerHandle handTracker, NiteHandTrackerFrame* pFrame) 00622 { 00623 release(); 00624 m_handTracker = handTracker; 00625 m_pFrame = pFrame; 00626 m_depthFrame._setFrame(pFrame->pDepthFrame); 00627 00628 m_hands.setData(m_pFrame->handCount, (HandData*)m_pFrame->pHands); 00629 m_gestures.setData(m_pFrame->gestureCount, (GestureData*)m_pFrame->pGestures); 00630 } 00631 00632 NiteHandTrackerFrame* m_pFrame; 00633 NiteHandTrackerHandle m_handTracker; 00634 openni::VideoFrameRef m_depthFrame; 00635 00636 Array<HandData> m_hands; 00637 Array<GestureData> m_gestures; 00638 }; 00639 00644 class HandTracker 00645 { 00646 public: 00647 class Listener 00648 { 00649 public: 00650 Listener() : m_pHandTracker(NULL) 00651 { 00652 m_handTrackerCallbacks.readyForNextFrame = newFrameCallback; 00653 } 00654 virtual void onNewFrame(HandTracker&) {} 00655 private: 00656 friend class HandTracker; 00657 NiteHandTrackerCallbacks m_handTrackerCallbacks; 00658 00659 NiteHandTrackerCallbacks& getCallbacks() {return m_handTrackerCallbacks;} 00660 00661 static void ONI_CALLBACK_TYPE newFrameCallback(void* pCookie) 00662 { 00663 Listener* pListener = (Listener*)pCookie; 00664 pListener->onNewFrame(*pListener->m_pHandTracker); 00665 } 00666 00667 void setHandTracker(HandTracker* pHandTracker) 00668 { 00669 m_pHandTracker = pHandTracker; 00670 } 00671 HandTracker* m_pHandTracker; 00672 }; 00673 00674 HandTracker() : m_handTrackerHandle(NULL) 00675 {} 00676 ~HandTracker() 00677 { 00678 destroy(); 00679 } 00680 00681 Status create(openni::Device* pDevice = NULL) 00682 { 00683 if (pDevice == NULL) 00684 { 00685 return (Status)niteInitializeHandTracker(&m_handTrackerHandle); 00686 // Pick a device 00687 } 00688 return (Status)niteInitializeHandTrackerByDevice(pDevice, &m_handTrackerHandle); 00689 } 00690 00691 void destroy() 00692 { 00693 if (isValid()) 00694 { 00695 niteShutdownHandTracker(m_handTrackerHandle); 00696 m_handTrackerHandle = NULL; 00697 } 00698 } 00699 00701 Status readFrame(HandTrackerFrameRef* pFrame) 00702 { 00703 NiteHandTrackerFrame *pNiteFrame = NULL; 00704 Status rc = (Status)niteReadHandTrackerFrame(m_handTrackerHandle, &pNiteFrame); 00705 pFrame->setReference(m_handTrackerHandle, pNiteFrame); 00706 00707 return rc; 00708 } 00709 00710 bool isValid() const 00711 { 00712 return m_handTrackerHandle != NULL; 00713 } 00714 00716 Status setSmoothingFactor(float factor) 00717 { 00718 return (Status)niteSetHandSmoothingFactor(m_handTrackerHandle, factor); 00719 } 00720 float getSmoothingFactor() const 00721 { 00722 float factor; 00723 Status rc = (Status)niteGetHandSmoothingFactor(m_handTrackerHandle, &factor); 00724 if (rc != STATUS_OK) 00725 { 00726 factor = 0; 00727 } 00728 return factor; 00729 } 00730 00735 Status startHandTracking(const Point3f& position, HandId* pNewHandId) 00736 { 00737 return (Status)niteStartHandTracking(m_handTrackerHandle, (const NitePoint3f*)&position, pNewHandId); 00738 } 00740 void stopHandTracking(HandId id) 00741 { 00742 niteStopHandTracking(m_handTrackerHandle, id); 00743 } 00744 00745 void addListener(Listener* pListener) 00746 { 00747 niteRegisterHandTrackerCallbacks(m_handTrackerHandle, &pListener->getCallbacks(), pListener); 00748 pListener->setHandTracker(this); 00749 } 00750 void removeListener(Listener* pListener) 00751 { 00752 niteUnregisterHandTrackerCallbacks(m_handTrackerHandle, &pListener->getCallbacks()); 00753 pListener->setHandTracker(NULL); 00754 } 00755 00757 Status startGestureDetection(GestureType type) 00758 { 00759 return (Status)niteStartGestureDetection(m_handTrackerHandle, (NiteGestureType)type); 00760 } 00762 void stopGestureDetection(GestureType type) 00763 { 00764 niteStopGestureDetection(m_handTrackerHandle, (NiteGestureType)type); 00765 } 00766 00772 Status convertHandCoordinatesToDepth(float x, float y, float z, float* pOutX, float* pOutY) const 00773 { 00774 return (Status)niteConvertHandCoordinatesToDepth(m_handTrackerHandle, x, y, z, pOutX, pOutY); 00775 } 00781 Status convertDepthCoordinatesToHand(int x, int y, int z, float* pOutX, float* pOutY) const 00782 { 00783 return (Status)niteConvertDepthCoordinatesToHand(m_handTrackerHandle, x, y, z, pOutX, pOutY); 00784 } 00785 00786 private: 00787 NiteHandTrackerHandle m_handTrackerHandle; 00788 }; 00789 00794 class NiTE 00795 { 00796 public: 00797 static Status initialize() 00798 { 00799 return (Status)niteInitialize(); 00800 } 00801 static void shutdown() 00802 { 00803 niteShutdown(); 00804 } 00805 00806 static Version getVersion() 00807 { 00808 NiteVersion version = niteGetVersion(); 00809 union 00810 { 00811 NiteVersion* pC; 00812 Version* pCpp; 00813 } a; 00814 a.pC = &version; 00815 return *a.pCpp; 00816 } 00817 private: 00818 NiTE(); 00819 }; 00820 00821 } // namespace nite 00822 00823 #endif // _NITE_H_