NiTE 2.0
NiTE.h
Go to the documentation of this file.
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_