![]() |
OpenNI 2.0
|
OpenNI.h
Go to the documentation of this file.
00001 /***************************************************************************** 00002 * * 00003 * OpenNI 2.x Alpha * 00004 * Copyright (C) 2012 PrimeSense Ltd. * 00005 * * 00006 * This file is part of OpenNI. * 00007 * * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); * 00009 * you may not use this file except in compliance with the License. * 00010 * You may obtain a copy of the License at * 00011 * * 00012 * http://www.apache.org/licenses/LICENSE-2.0 * 00013 * * 00014 * Unless required by applicable law or agreed to in writing, software * 00015 * distributed under the License is distributed on an "AS IS" BASIS, * 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00017 * See the License for the specific language governing permissions and * 00018 * limitations under the License. * 00019 * * 00020 *****************************************************************************/ 00021 #ifndef _OPENNI_H_ 00022 #define _OPENNI_H_ 00023 00024 #include "OniPlatform.h" 00025 #include "OniProperties.h" 00026 #include "OniEnums.h" 00027 00028 #include "OniCAPI.h" 00029 #include "OniCProperties.h" 00030 00034 namespace openni 00035 { 00036 00038 typedef uint16_t DepthPixel; 00039 00041 typedef uint16_t Grayscale16Pixel; 00042 00043 // structs 00045 typedef struct 00046 { 00048 int major; 00050 int minor; 00052 int maintenance; 00054 int build; 00055 } Version; 00056 00058 typedef struct 00059 { 00060 /* Red value of this pixel. */ 00061 uint8_t r; 00062 /* Green value of this pixel. */ 00063 uint8_t g; 00064 /* Blue value of this pixel. */ 00065 uint8_t b; 00066 } RGB888Pixel; 00067 00073 typedef struct 00074 { 00076 uint8_t u; 00078 uint8_t y1; 00080 uint8_t v; 00082 uint8_t y2; 00083 } YUV422DoublePixel; 00084 00086 #if ONI_PLATFORM != ONI_PLATFORM_WIN32 00087 #pragma GCC diagnostic ignored "-Wunused-variable" 00088 #pragma GCC diagnostic push 00089 #endif 00090 static const char* ANY_DEVICE = NULL; 00091 #if ONI_PLATFORM != ONI_PLATFORM_WIN32 00092 #pragma GCC diagnostic pop 00093 #endif 00094 00099 template<class T> 00100 class Array 00101 { 00102 public: 00106 Array() : m_data(NULL), m_count(0), m_owner(false) {} 00107 00115 Array(const T* data, int count) : m_owner(false) { _setData(data, count); } 00116 00120 ~Array() 00121 { 00122 clear(); 00123 } 00124 00129 int getSize() const { return m_count; } 00130 00134 const T& operator[](int index) const {return m_data[index];} 00135 00146 void _setData(const T* data, int count, bool isOwner = false) 00147 { 00148 clear(); 00149 m_count = count; 00150 m_owner = isOwner; 00151 if (!isOwner) 00152 { 00153 m_data = data; 00154 } 00155 else 00156 { 00157 m_data = new T[count]; 00158 memcpy((void*)m_data, data, count*sizeof(T)); 00159 } 00160 } 00161 00162 private: 00163 Array(const Array<T>&); 00164 Array<T>& operator=(const Array<T>&); 00165 00166 void clear() 00167 { 00168 if (m_owner && m_data != NULL) 00169 delete []m_data; 00170 m_owner = false; 00171 m_data = NULL; 00172 m_count = 0; 00173 } 00174 00175 const T* m_data; 00176 int m_count; 00177 bool m_owner; 00178 }; 00179 00180 // Forward declaration of all 00181 class SensorInfo; 00182 class VideoStream; 00183 class VideoFrameRef; 00184 class Device; 00185 class OpenNI; 00186 class CameraSettings; 00187 class PlaybackControl; 00188 00203 class VideoMode : private OniVideoMode 00204 { 00205 public: 00211 VideoMode() 00212 {} 00213 00219 VideoMode(const VideoMode& other) 00220 { 00221 *this = other; 00222 } 00223 00230 VideoMode& operator=(const VideoMode& other) 00231 { 00232 setPixelFormat(other.getPixelFormat()); 00233 setResolution(other.getResolutionX(), other.getResolutionY()); 00234 setFps(other.getFps()); 00235 00236 return *this; 00237 } 00238 00243 PixelFormat getPixelFormat() const { return (PixelFormat)pixelFormat; } 00244 00249 int getResolutionX() const { return resolutionX; } 00250 00255 int getResolutionY() const {return resolutionY;} 00256 00261 int getFps() const { return fps; } 00262 00269 void setPixelFormat(PixelFormat format) { this->pixelFormat = (OniPixelFormat)format; } 00270 00278 void setResolution(int resolutionX, int resolutionY) 00279 { 00280 this->resolutionX = resolutionX; 00281 this->resolutionY = resolutionY; 00282 } 00283 00290 void setFps(int fps) { this->fps = fps; } 00291 00292 friend class SensorInfo; 00293 friend class VideoStream; 00294 friend class VideoFrameRef; 00295 }; 00296 00314 class SensorInfo 00315 { 00316 public: 00321 SensorType getSensorType() const { return (SensorType)m_pInfo->sensorType; } 00322 00330 const Array<VideoMode>& getSupportedVideoModes() const { return m_videoModes; } 00331 00332 private: 00333 SensorInfo(const SensorInfo&); 00334 SensorInfo& operator=(const SensorInfo&); 00335 00336 SensorInfo() : m_pInfo(NULL), m_videoModes(NULL, 0) {} 00337 00338 SensorInfo(const OniSensorInfo* pInfo) : m_pInfo(NULL), m_videoModes(NULL, 0) 00339 { 00340 _setInternal(pInfo); 00341 } 00342 00343 void _setInternal(const OniSensorInfo* pInfo) 00344 { 00345 m_pInfo = pInfo; 00346 if (pInfo == NULL) 00347 { 00348 m_videoModes._setData(NULL, 0); 00349 } 00350 else 00351 { 00352 m_videoModes._setData(static_cast<VideoMode*>(pInfo->pSupportedVideoModes), pInfo->numSupportedVideoModes); 00353 } 00354 } 00355 00356 const OniSensorInfo* m_pInfo; 00357 Array<VideoMode> m_videoModes; 00358 00359 friend class VideoStream; 00360 friend class Device; 00361 }; 00362 00372 class DeviceInfo : private OniDeviceInfo 00373 { 00374 public: 00379 const char* getUri() const { return uri; } 00381 const char* getVendor() const { return vendor; } 00383 const char* getName() const { return name; } 00385 uint16_t getUsbVendorId() const { return usbVendorId; } 00387 uint16_t getUsbProductId() const { return usbProductId; } 00388 00389 friend class Device; 00390 friend class OpenNI; 00391 }; 00392 00406 class VideoFrameRef 00407 { 00408 public: 00413 VideoFrameRef() 00414 { 00415 m_pFrame = NULL; 00416 } 00417 00421 ~VideoFrameRef() 00422 { 00423 release(); 00424 } 00425 00431 VideoFrameRef(const VideoFrameRef& other) : m_pFrame(NULL) 00432 { 00433 _setFrame(other.m_pFrame); 00434 } 00435 00441 VideoFrameRef& operator=(const VideoFrameRef& other) 00442 { 00443 _setFrame(other.m_pFrame); 00444 return *this; 00445 } 00446 00452 inline int getDataSize() const 00453 { 00454 return m_pFrame->dataSize; 00455 } 00456 00462 inline const void* getData() const 00463 { 00464 return m_pFrame->data; 00465 } 00466 00473 inline SensorType getSensorType() const 00474 { 00475 return (SensorType)m_pFrame->sensorType; 00476 } 00477 00485 inline const VideoMode& getVideoMode() const 00486 { 00487 return static_cast<const VideoMode&>(m_pFrame->videoMode); 00488 } 00489 00497 inline uint64_t getTimestamp() const 00498 { 00499 return m_pFrame->timestamp; 00500 } 00501 00512 inline int getFrameIndex() const 00513 { 00514 return m_pFrame->frameIndex; 00515 } 00516 00523 inline int getWidth() const 00524 { 00525 return m_pFrame->width; 00526 } 00527 00533 inline int getHeight() const 00534 { 00535 return m_pFrame->height; 00536 } 00537 00542 inline bool getCroppingEnabled() const 00543 { 00544 return m_pFrame->croppingEnabled == TRUE; 00545 } 00546 00551 inline int getCropOriginX() const 00552 { 00553 return m_pFrame->cropOriginX; 00554 } 00555 00560 inline int getCropOriginY() const 00561 { 00562 return m_pFrame->cropOriginY; 00563 } 00564 00570 inline int getStrideInBytes() const 00571 { 00572 return m_pFrame->stride; 00573 } 00574 00578 inline bool isValid() const 00579 { 00580 return m_pFrame != NULL; 00581 } 00582 00587 void release() 00588 { 00589 if (m_pFrame != NULL) 00590 { 00591 oniFrameRelease(m_pFrame); 00592 m_pFrame = NULL; 00593 } 00594 } 00595 00597 void _setFrame(OniFrame* pFrame) 00598 { 00599 setReference(pFrame); 00600 if (pFrame != NULL) 00601 { 00602 oniFrameAddRef(pFrame); 00603 } 00604 } 00605 00607 OniFrame* _getFrame() 00608 { 00609 return m_pFrame; 00610 } 00611 00612 private: 00613 friend class VideoStream; 00614 inline void setReference(OniFrame* pFrame) 00615 { 00616 // Initial - don't addref. This is the reference from OpenNI 00617 release(); 00618 m_pFrame = pFrame; 00619 } 00620 00621 OniFrame* m_pFrame; // const!!? 00622 }; 00623 00645 class VideoStream 00646 { 00647 public: 00655 class NewFrameListener 00656 { 00657 public: 00661 NewFrameListener() : m_callbackHandle(NULL) 00662 { 00663 } 00664 00665 virtual ~NewFrameListener() 00666 { 00667 } 00668 00672 virtual void onNewFrame(VideoStream&) = 0; 00673 00674 private: 00675 friend class VideoStream; 00676 00677 static void ONI_CALLBACK_TYPE callback(OniStreamHandle streamHandle, void* pCookie) 00678 { 00679 NewFrameListener* pListener = (NewFrameListener*)pCookie; 00680 VideoStream stream; 00681 stream._setHandle(streamHandle); 00682 pListener->onNewFrame(stream); 00683 stream._setHandle(NULL); 00684 } 00685 OniCallbackHandle m_callbackHandle; 00686 }; 00687 00688 class FrameAllocator 00689 { 00690 public: 00691 virtual ~FrameAllocator() {} 00692 virtual void* allocateFrameBuffer(int size) = 0; 00693 virtual void freeFrameBuffer(void* data) = 0; 00694 00695 private: 00696 friend class VideoStream; 00697 00698 static void* ONI_CALLBACK_TYPE allocateFrameBufferCallback(int size, void* pCookie) 00699 { 00700 FrameAllocator* pThis = (FrameAllocator*)pCookie; 00701 return pThis->allocateFrameBuffer(size); 00702 } 00703 00704 static void ONI_CALLBACK_TYPE freeFrameBufferCallback(void* data, void* pCookie) 00705 { 00706 FrameAllocator* pThis = (FrameAllocator*)pCookie; 00707 pThis->freeFrameBuffer(data); 00708 } 00709 }; 00710 00715 VideoStream() : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(true) 00716 {} 00717 00722 explicit VideoStream(OniStreamHandle handle) : m_stream(NULL), m_sensorInfo(), m_pCameraSettings(NULL), m_isOwner(false) 00723 { 00724 _setHandle(handle); 00725 } 00726 00731 ~VideoStream() 00732 { 00733 destroy(); 00734 } 00735 00740 bool isValid() const 00741 { 00742 return m_stream != NULL; 00743 } 00744 00754 inline Status create(const Device& device, SensorType sensorType); 00755 00761 inline void destroy(); 00762 00771 const SensorInfo& getSensorInfo() const 00772 { 00773 return m_sensorInfo; 00774 } 00775 00779 Status start() 00780 { 00781 if (!isValid()) 00782 { 00783 return STATUS_ERROR; 00784 } 00785 00786 return (Status)oniStreamStart(m_stream); 00787 } 00788 00792 void stop() 00793 { 00794 if (!isValid()) 00795 { 00796 return; 00797 } 00798 00799 oniStreamStop(m_stream); 00800 } 00801 00812 Status readFrame(VideoFrameRef* pFrame) 00813 { 00814 if (!isValid()) 00815 { 00816 return STATUS_ERROR; 00817 } 00818 00819 OniFrame* pOniFrame; 00820 Status rc = (Status)oniStreamReadFrame(m_stream, &pOniFrame); 00821 00822 pFrame->setReference(pOniFrame); 00823 return rc; 00824 } 00825 00833 Status addNewFrameListener(NewFrameListener* pListener) 00834 { 00835 if (!isValid()) 00836 { 00837 return STATUS_ERROR; 00838 } 00839 00840 return (Status)oniStreamRegisterNewFrameCallback(m_stream, pListener->callback, pListener, &pListener->m_callbackHandle); 00841 } 00842 00847 void removeNewFrameListener(NewFrameListener* pListener) 00848 { 00849 if (!isValid()) 00850 { 00851 return; 00852 } 00853 00854 oniStreamUnregisterNewFrameCallback(m_stream, pListener->m_callbackHandle); 00855 pListener->m_callbackHandle = NULL; 00856 } 00857 00863 Status setFrameBuffersAllocator(FrameAllocator* pAllocator) 00864 { 00865 if (!isValid()) 00866 { 00867 return STATUS_ERROR; 00868 } 00869 00870 if (pAllocator == NULL) 00871 { 00872 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, NULL, NULL, NULL); 00873 } 00874 else 00875 { 00876 return (Status)oniStreamSetFrameBuffersAllocator(m_stream, pAllocator->allocateFrameBufferCallback, pAllocator->freeFrameBufferCallback, pAllocator); 00877 } 00878 } 00879 00884 OniStreamHandle _getHandle() const 00885 { 00886 return m_stream; 00887 } 00888 00893 CameraSettings* getCameraSettings() {return m_pCameraSettings;} 00894 00905 Status getProperty(int propertyId, void* data, int* dataSize) const 00906 { 00907 if (!isValid()) 00908 { 00909 return STATUS_ERROR; 00910 } 00911 00912 return (Status)oniStreamGetProperty(m_stream, propertyId, data, dataSize); 00913 } 00914 00925 Status setProperty(int propertyId, const void* data, int dataSize) 00926 { 00927 if (!isValid()) 00928 { 00929 return STATUS_ERROR; 00930 } 00931 00932 return (Status)oniStreamSetProperty(m_stream, propertyId, data, dataSize); 00933 } 00934 00941 VideoMode getVideoMode() const 00942 { 00943 VideoMode videoMode; 00944 getProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<OniVideoMode*>(&videoMode)); 00945 return videoMode; 00946 } 00947 00956 Status setVideoMode(const VideoMode& videoMode) 00957 { 00958 return setProperty<OniVideoMode>(STREAM_PROPERTY_VIDEO_MODE, static_cast<const OniVideoMode&>(videoMode)); 00959 } 00960 00966 int getMaxPixelValue() const 00967 { 00968 int maxValue; 00969 Status rc = getProperty<int>(STREAM_PROPERTY_MAX_VALUE, &maxValue); 00970 if (rc != STATUS_OK) 00971 { 00972 return 0; 00973 } 00974 return maxValue; 00975 } 00976 00982 int getMinPixelValue() const 00983 { 00984 int minValue; 00985 Status rc = getProperty<int>(STREAM_PROPERTY_MIN_VALUE, &minValue); 00986 if (rc != STATUS_OK) 00987 { 00988 return 0; 00989 } 00990 return minValue; 00991 } 00992 00997 bool isCroppingSupported() const 00998 { 00999 return isPropertySupported(STREAM_PROPERTY_CROPPING); 01000 } 01001 01010 bool getCropping(int* pOriginX, int* pOriginY, int* pWidth, int* pHeight) const 01011 { 01012 OniCropping cropping; 01013 bool enabled = false; 01014 01015 Status rc = getProperty<OniCropping>(STREAM_PROPERTY_CROPPING, &cropping); 01016 01017 if (rc == STATUS_OK) 01018 { 01019 *pOriginX = cropping.originX; 01020 *pOriginY = cropping.originY; 01021 *pWidth = cropping.width; 01022 *pHeight = cropping.height; 01023 enabled = (cropping.enabled == TRUE); 01024 } 01025 01026 return enabled; 01027 } 01028 01038 Status setCropping(int originX, int originY, int width, int height) 01039 { 01040 OniCropping cropping; 01041 cropping.enabled = true; 01042 cropping.originX = originX; 01043 cropping.originY = originY; 01044 cropping.width = width; 01045 cropping.height = height; 01046 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 01047 } 01048 01053 Status resetCropping() 01054 { 01055 OniCropping cropping; 01056 cropping.enabled = false; 01057 return setProperty<OniCropping>(STREAM_PROPERTY_CROPPING, cropping); 01058 } 01059 01064 bool getMirroringEnabled() const 01065 { 01066 OniBool enabled; 01067 Status rc = getProperty<OniBool>(STREAM_PROPERTY_MIRRORING, &enabled); 01068 if (rc != STATUS_OK) 01069 { 01070 return false; 01071 } 01072 return enabled == TRUE; 01073 } 01074 01080 Status setMirroringEnabled(bool isEnabled) 01081 { 01082 return setProperty<OniBool>(STREAM_PROPERTY_MIRRORING, isEnabled ? TRUE : FALSE); 01083 } 01084 01089 float getHorizontalFieldOfView() const 01090 { 01091 float horizontal = 0; 01092 getProperty<float>(STREAM_PROPERTY_HORIZONTAL_FOV, &horizontal); 01093 return horizontal; 01094 } 01095 01100 float getVerticalFieldOfView() const 01101 { 01102 float vertical = 0; 01103 getProperty<float>(STREAM_PROPERTY_VERTICAL_FOV, &vertical); 01104 return vertical; 01105 } 01106 01116 template <class T> 01117 Status setProperty(int propertyId, const T& value) 01118 { 01119 return setProperty(propertyId, &value, sizeof(T)); 01120 } 01121 01131 template <class T> 01132 Status getProperty(int propertyId, T* value) const 01133 { 01134 int size = sizeof(T); 01135 return getProperty(propertyId, value, &size); 01136 } 01137 01143 bool isPropertySupported(int propertyId) const 01144 { 01145 if (!isValid()) 01146 { 01147 return false; 01148 } 01149 01150 return oniStreamIsPropertySupported(m_stream, propertyId) == TRUE; 01151 } 01152 01162 Status invoke(int commandId, void* data, int dataSize) 01163 { 01164 if (!isValid()) 01165 { 01166 return STATUS_ERROR; 01167 } 01168 01169 return (Status)oniStreamInvoke(m_stream, commandId, data, dataSize); 01170 } 01171 01181 template <class T> 01182 Status invoke(int commandId, T& value) 01183 { 01184 return invoke(commandId, &value, sizeof(T)); 01185 } 01186 01192 bool isCommandSupported(int commandId) const 01193 { 01194 if (!isValid()) 01195 { 01196 return false; 01197 } 01198 01199 return (Status)oniStreamIsCommandSupported(m_stream, commandId) == TRUE; 01200 } 01201 01202 private: 01203 friend class Device; 01204 01205 void _setHandle(OniStreamHandle stream) 01206 { 01207 m_sensorInfo._setInternal(NULL); 01208 m_stream = stream; 01209 01210 if (stream != NULL) 01211 { 01212 m_sensorInfo._setInternal(oniStreamGetSensorInfo(m_stream)); 01213 } 01214 } 01215 01216 private: 01217 VideoStream(const VideoStream& other); 01218 VideoStream& operator=(const VideoStream& other); 01219 01220 OniStreamHandle m_stream; 01221 SensorInfo m_sensorInfo; 01222 CameraSettings* m_pCameraSettings; 01223 bool m_isOwner; 01224 }; 01225 01242 class Device 01243 { 01244 public: 01249 Device() : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(true) 01250 { 01251 clearSensors(); 01252 } 01253 01258 explicit Device(OniDeviceHandle handle) : m_pPlaybackControl(NULL), m_device(NULL), m_isOwner(false) 01259 { 01260 _setHandle(handle); 01261 } 01262 01267 ~Device() 01268 { 01269 if (m_device != NULL) 01270 { 01271 close(); 01272 } 01273 } 01274 01304 inline Status open(const char* uri); 01305 01311 inline void close(); 01312 01322 const DeviceInfo& getDeviceInfo() const 01323 { 01324 return m_deviceInfo; 01325 } 01326 01334 bool hasSensor(SensorType sensorType) 01335 { 01336 int i; 01337 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01338 { 01339 if (m_aSensorInfo[i].getSensorType() == sensorType) 01340 { 01341 return true; 01342 } 01343 } 01344 01345 if (i == ONI_MAX_SENSORS) 01346 { 01347 return false; 01348 } 01349 01350 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01351 01352 if (pInfo == NULL) 01353 { 01354 return false; 01355 } 01356 01357 m_aSensorInfo[i]._setInternal(pInfo); 01358 01359 return true; 01360 } 01361 01369 const SensorInfo* getSensorInfo(SensorType sensorType) 01370 { 01371 int i; 01372 for (i = 0; (i < ONI_MAX_SENSORS) && (m_aSensorInfo[i].m_pInfo != NULL); ++i) 01373 { 01374 if (m_aSensorInfo[i].getSensorType() == sensorType) 01375 { 01376 return &m_aSensorInfo[i]; 01377 } 01378 } 01379 01380 // not found. check to see we have additional space 01381 if (i == ONI_MAX_SENSORS) 01382 { 01383 return NULL; 01384 } 01385 01386 const OniSensorInfo* pInfo = oniDeviceGetSensorInfo(m_device, (OniSensorType)sensorType); 01387 if (pInfo == NULL) 01388 { 01389 return NULL; 01390 } 01391 01392 m_aSensorInfo[i]._setInternal(pInfo); 01393 return &m_aSensorInfo[i]; 01394 } 01395 01400 OniDeviceHandle _getHandle() const 01401 { 01402 return m_device; 01403 } 01404 01409 PlaybackControl* getPlaybackControl() {return m_pPlaybackControl;} 01410 01422 Status getProperty(int propertyId, void* data, int* dataSize) const 01423 { 01424 return (Status)oniDeviceGetProperty(m_device, propertyId, data, dataSize); 01425 } 01426 01438 Status setProperty(int propertyId, const void* data, int dataSize) 01439 { 01440 return (Status)oniDeviceSetProperty(m_device, propertyId, data, dataSize); 01441 } 01442 01450 bool isImageRegistrationModeSupported(ImageRegistrationMode mode) const 01451 { 01452 return (oniDeviceIsImageRegistrationModeSupported(m_device, (OniImageRegistrationMode)mode) == TRUE); 01453 } 01454 01462 ImageRegistrationMode getImageRegistrationMode() const 01463 { 01464 ImageRegistrationMode mode; 01465 Status rc = getProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, &mode); 01466 if (rc != STATUS_OK) 01467 { 01468 return IMAGE_REGISTRATION_OFF; 01469 } 01470 return mode; 01471 } 01472 01486 Status setImageRegistrationMode(ImageRegistrationMode mode) 01487 { 01488 return setProperty<ImageRegistrationMode>(DEVICE_PROPERTY_IMAGE_REGISTRATION, mode); 01489 } 01490 01495 bool isValid() const 01496 { 01497 return m_device != NULL; 01498 } 01499 01504 bool isFile() const 01505 { 01506 return isPropertySupported(DEVICE_PROPERTY_PLAYBACK_SPEED) && 01507 isPropertySupported(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED) && 01508 isCommandSupported(DEVICE_COMMAND_SEEK); 01509 } 01510 01519 Status setDepthColorSyncEnabled(bool isEnabled) 01520 { 01521 Status rc = STATUS_OK; 01522 01523 if (isEnabled) 01524 { 01525 rc = (Status)oniDeviceEnableDepthColorSync(m_device); 01526 } 01527 else 01528 { 01529 oniDeviceDisableDepthColorSync(m_device); 01530 } 01531 01532 return rc; 01533 } 01534 01535 bool getDepthColorSyncEnabled() 01536 { 01537 return oniDeviceGetDepthColorSyncEnabled(m_device) == TRUE; 01538 } 01539 01550 template <class T> 01551 Status setProperty(int propertyId, const T& value) 01552 { 01553 return setProperty(propertyId, &value, sizeof(T)); 01554 } 01555 01565 template <class T> 01566 Status getProperty(int propertyId, T* value) const 01567 { 01568 int size = sizeof(T); 01569 return getProperty(propertyId, value, &size); 01570 } 01571 01577 bool isPropertySupported(int propertyId) const 01578 { 01579 return oniDeviceIsPropertySupported(m_device, propertyId) == TRUE; 01580 } 01581 01591 Status invoke(int commandId, void* data, int dataSize) 01592 { 01593 return (Status)oniDeviceInvoke(m_device, commandId, data, dataSize); 01594 } 01595 01605 template <class T> 01606 Status invoke(int propertyId, T& value) 01607 { 01608 return invoke(propertyId, &value, sizeof(T)); 01609 } 01610 01616 bool isCommandSupported(int commandId) const 01617 { 01618 return oniDeviceIsCommandSupported(m_device, commandId) == TRUE; 01619 } 01620 01622 inline Status _openEx(const char* uri, const char* mode); 01623 01624 private: 01625 Device(const Device&); 01626 Device& operator=(const Device&); 01627 01628 void clearSensors() 01629 { 01630 for (int i = 0; i < ONI_MAX_SENSORS; ++i) 01631 { 01632 m_aSensorInfo[i]._setInternal(NULL); 01633 } 01634 } 01635 01636 inline Status _setHandle(OniDeviceHandle deviceHandle); 01637 01638 private: 01639 PlaybackControl* m_pPlaybackControl; 01640 01641 OniDeviceHandle m_device; 01642 DeviceInfo m_deviceInfo; 01643 SensorInfo m_aSensorInfo[ONI_MAX_SENSORS]; 01644 01645 bool m_isOwner; 01646 }; 01647 01661 class PlaybackControl 01662 { 01663 public: 01664 01670 ~PlaybackControl() 01671 { 01672 detach(); 01673 } 01674 01695 float getSpeed() const 01696 { 01697 if (!isValid()) 01698 { 01699 return 0.0f; 01700 } 01701 float speed; 01702 Status rc = m_pDevice->getProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, &speed); 01703 if (rc != STATUS_OK) 01704 { 01705 return 1.0f; 01706 } 01707 return speed; 01708 } 01716 Status setSpeed(float speed) 01717 { 01718 if (!isValid()) 01719 { 01720 return STATUS_NO_DEVICE; 01721 } 01722 return m_pDevice->setProperty<float>(DEVICE_PROPERTY_PLAYBACK_SPEED, speed); 01723 } 01724 01730 bool getRepeatEnabled() const 01731 { 01732 if (!isValid()) 01733 { 01734 return false; 01735 } 01736 01737 OniBool repeat; 01738 Status rc = m_pDevice->getProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, &repeat); 01739 if (rc != STATUS_OK) 01740 { 01741 return false; 01742 } 01743 01744 return repeat == TRUE; 01745 } 01746 01755 Status setRepeatEnabled(bool repeat) 01756 { 01757 if (!isValid()) 01758 { 01759 return STATUS_NO_DEVICE; 01760 } 01761 01762 return m_pDevice->setProperty<OniBool>(DEVICE_PROPERTY_PLAYBACK_REPEAT_ENABLED, repeat ? TRUE : FALSE); 01763 } 01764 01775 Status seek(const VideoStream& stream, int frameIndex) 01776 { 01777 if (!isValid()) 01778 { 01779 return STATUS_NO_DEVICE; 01780 } 01781 OniSeek seek; 01782 seek.frameIndex = frameIndex; 01783 seek.stream = stream._getHandle(); 01784 return m_pDevice->invoke(DEVICE_COMMAND_SEEK, seek); 01785 } 01786 01795 int getNumberOfFrames(const VideoStream& stream) const 01796 { 01797 int numOfFrames = -1; 01798 Status rc = stream.getProperty<int>(STREAM_PROPERTY_NUMBER_OF_FRAMES, &numOfFrames); 01799 if (rc != STATUS_OK) 01800 { 01801 return 0; 01802 } 01803 return numOfFrames; 01804 } 01805 01806 bool isValid() const 01807 { 01808 return m_pDevice != NULL; 01809 } 01810 private: 01811 Status attach(Device* device) 01812 { 01813 if (!device->isValid() || !device->isFile()) 01814 { 01815 return STATUS_ERROR; 01816 } 01817 01818 detach(); 01819 m_pDevice = device; 01820 01821 return STATUS_OK; 01822 } 01823 void detach() 01824 { 01825 m_pDevice = NULL; 01826 } 01827 01828 friend class Device; 01829 PlaybackControl(Device* pDevice) : m_pDevice(NULL) 01830 { 01831 if (pDevice != NULL) 01832 { 01833 attach(pDevice); 01834 } 01835 } 01836 01837 Device* m_pDevice; 01838 }; 01839 01840 class CameraSettings 01841 { 01842 public: 01843 // setters 01844 Status setAutoExposureEnabled(bool enabled) 01845 { 01846 return setProperty(STREAM_PROPERTY_AUTO_EXPOSURE, enabled ? TRUE : FALSE); 01847 } 01848 Status setAutoWhiteBalanceEnabled(bool enabled) 01849 { 01850 return setProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, enabled ? TRUE : FALSE); 01851 } 01852 01853 bool getAutoExposureEnabled() const 01854 { 01855 OniBool enabled = FALSE; 01856 01857 Status rc = getProperty(STREAM_PROPERTY_AUTO_EXPOSURE, &enabled); 01858 return rc == STATUS_OK && enabled == TRUE; 01859 } 01860 bool getAutoWhiteBalanceEnabled() const 01861 { 01862 OniBool enabled = FALSE; 01863 01864 Status rc = getProperty(STREAM_PROPERTY_AUTO_WHITE_BALANCE, &enabled); 01865 return rc == STATUS_OK && enabled == TRUE; 01866 } 01867 01868 Status setGain(int gain) 01869 { 01870 return setProperty(STREAM_PROPERTY_GAIN, gain); 01871 } 01872 Status setExposure(int exposure) 01873 { 01874 return setProperty(STREAM_PROPERTY_EXPOSURE, exposure); 01875 } 01876 int getGain() 01877 { 01878 int gain; 01879 Status rc = getProperty(STREAM_PROPERTY_GAIN, &gain); 01880 if (rc != STATUS_OK) 01881 { 01882 return 100; 01883 } 01884 return gain; 01885 } 01886 int getExposure() 01887 { 01888 int exposure; 01889 Status rc = getProperty(STREAM_PROPERTY_EXPOSURE, &exposure); 01890 if (rc != STATUS_OK) 01891 { 01892 return 0; 01893 } 01894 return exposure; 01895 } 01896 01897 bool isValid() const {return m_pStream != NULL;} 01898 private: 01899 template <class T> 01900 Status getProperty(int propertyId, T* value) const 01901 { 01902 if (!isValid()) return STATUS_NOT_SUPPORTED; 01903 01904 return m_pStream->getProperty<T>(propertyId, value); 01905 } 01906 template <class T> 01907 Status setProperty(int propertyId, const T& value) 01908 { 01909 if (!isValid()) return STATUS_NOT_SUPPORTED; 01910 01911 return m_pStream->setProperty<T>(propertyId, value); 01912 } 01913 01914 friend class VideoStream; 01915 CameraSettings(VideoStream* pStream) 01916 { 01917 m_pStream = pStream; 01918 } 01919 01920 VideoStream* m_pStream; 01921 }; 01922 01923 01936 class OpenNI 01937 { 01938 public: 01939 01955 class DeviceConnectedListener 01956 { 01957 public: 01958 DeviceConnectedListener() 01959 { 01960 m_deviceConnectedCallbacks.deviceConnected = deviceConnectedCallback; 01961 m_deviceConnectedCallbacks.deviceDisconnected = NULL; 01962 m_deviceConnectedCallbacks.deviceStateChanged = NULL; 01963 m_deviceConnectedCallbacksHandle = NULL; 01964 } 01965 01966 virtual ~DeviceConnectedListener() 01967 { 01968 } 01969 01981 virtual void onDeviceConnected(const DeviceInfo*) = 0; 01982 private: 01983 static void ONI_CALLBACK_TYPE deviceConnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 01984 { 01985 DeviceConnectedListener* pListener = (DeviceConnectedListener*)pCookie; 01986 pListener->onDeviceConnected(static_cast<const DeviceInfo*>(pInfo)); 01987 } 01988 01989 friend class OpenNI; 01990 OniDeviceCallbacks m_deviceConnectedCallbacks; 01991 OniCallbackHandle m_deviceConnectedCallbacksHandle; 01992 01993 }; 02010 class DeviceDisconnectedListener 02011 { 02012 public: 02013 DeviceDisconnectedListener() 02014 { 02015 m_deviceDisconnectedCallbacks.deviceConnected = NULL; 02016 m_deviceDisconnectedCallbacks.deviceDisconnected = deviceDisconnectedCallback; 02017 m_deviceDisconnectedCallbacks.deviceStateChanged = NULL; 02018 m_deviceDisconnectedCallbacksHandle = NULL; 02019 } 02020 02021 virtual ~DeviceDisconnectedListener() 02022 { 02023 } 02024 02033 virtual void onDeviceDisconnected(const DeviceInfo*) = 0; 02034 private: 02035 static void ONI_CALLBACK_TYPE deviceDisconnectedCallback(const OniDeviceInfo* pInfo, void* pCookie) 02036 { 02037 DeviceDisconnectedListener* pListener = (DeviceDisconnectedListener*)pCookie; 02038 pListener->onDeviceDisconnected(static_cast<const DeviceInfo*>(pInfo)); 02039 } 02040 02041 friend class OpenNI; 02042 OniDeviceCallbacks m_deviceDisconnectedCallbacks; 02043 OniCallbackHandle m_deviceDisconnectedCallbacksHandle; 02044 }; 02058 class DeviceStateChangedListener 02059 { 02060 public: 02061 DeviceStateChangedListener() 02062 { 02063 m_deviceStateChangedCallbacks.deviceConnected = NULL; 02064 m_deviceStateChangedCallbacks.deviceDisconnected = NULL; 02065 m_deviceStateChangedCallbacks.deviceStateChanged = deviceStateChangedCallback; 02066 m_deviceStateChangedCallbacksHandle = NULL; 02067 } 02068 02069 virtual ~DeviceStateChangedListener() 02070 { 02071 } 02072 02079 virtual void onDeviceStateChanged(const DeviceInfo*, DeviceState) = 0; 02080 private: 02081 static void ONI_CALLBACK_TYPE deviceStateChangedCallback(const OniDeviceInfo* pInfo, OniDeviceState state, void* pCookie) 02082 { 02083 DeviceStateChangedListener* pListener = (DeviceStateChangedListener*)pCookie; 02084 pListener->onDeviceStateChanged(static_cast<const DeviceInfo*>(pInfo), DeviceState(state)); 02085 } 02086 02087 friend class OpenNI; 02088 OniDeviceCallbacks m_deviceStateChangedCallbacks; 02089 OniCallbackHandle m_deviceStateChangedCallbacksHandle; 02090 }; 02091 02097 static Status initialize() 02098 { 02099 return (Status)oniInitialize(ONI_API_VERSION); // provide version of API, to make sure proper struct sizes are used 02100 } 02101 02106 static void shutdown() 02107 { 02108 oniShutdown(); 02109 } 02110 02114 static Version getVersion() 02115 { 02116 OniVersion oniVersion = oniGetVersion(); 02117 Version version; 02118 version.major = oniVersion.major; 02119 version.minor = oniVersion.minor; 02120 version.maintenance = oniVersion.maintenance; 02121 version.build = oniVersion.build; 02122 return version; 02123 } 02124 02132 static const char* getExtendedError() 02133 { 02134 return oniGetExtendedError(); 02135 } 02136 02141 static void enumerateDevices(Array<DeviceInfo>* deviceInfoList) 02142 { 02143 OniDeviceInfo* m_pDeviceInfos; 02144 int m_deviceInfoCount; 02145 oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount); 02146 deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true); 02147 oniReleaseDeviceList(m_pDeviceInfos); 02148 } 02149 02158 static Status waitForAnyStream(VideoStream** pStreams, int streamCount, int* pReadyStreamIndex, int timeout = TIMEOUT_FOREVER) 02159 { 02160 static const int ONI_MAX_STREAMS = 50; 02161 OniStreamHandle streams[ONI_MAX_STREAMS]; 02162 02163 if (streamCount > ONI_MAX_STREAMS) 02164 { 02165 printf("Too many streams for wait: %d > %d\n", streamCount, ONI_MAX_STREAMS); 02166 return STATUS_BAD_PARAMETER; 02167 } 02168 02169 *pReadyStreamIndex = -1; 02170 for (int i = 0; i < streamCount; ++i) 02171 { 02172 if (pStreams[i] != NULL) 02173 { 02174 streams[i] = pStreams[i]->_getHandle(); 02175 } 02176 else 02177 { 02178 streams[i] = NULL; 02179 } 02180 } 02181 Status rc = (Status)oniWaitForAnyStream(streams, streamCount, pReadyStreamIndex, timeout); 02182 02183 return rc; 02184 } 02185 02193 static Status addDeviceConnectedListener(DeviceConnectedListener* pListener) 02194 { 02195 if (pListener->m_deviceConnectedCallbacksHandle != NULL) 02196 { 02197 return STATUS_ERROR; 02198 } 02199 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceConnectedCallbacks, pListener, &pListener->m_deviceConnectedCallbacksHandle); 02200 } 02208 static Status addDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02209 { 02210 if (pListener->m_deviceDisconnectedCallbacksHandle != NULL) 02211 { 02212 return STATUS_ERROR; 02213 } 02214 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceDisconnectedCallbacks, pListener, &pListener->m_deviceDisconnectedCallbacksHandle); 02215 } 02223 static Status addDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02224 { 02225 if (pListener->m_deviceStateChangedCallbacksHandle != NULL) 02226 { 02227 return STATUS_ERROR; 02228 } 02229 return (Status)oniRegisterDeviceCallbacks(&pListener->m_deviceStateChangedCallbacks, pListener, &pListener->m_deviceStateChangedCallbacksHandle); 02230 } 02238 static void removeDeviceConnectedListener(DeviceConnectedListener* pListener) 02239 { 02240 oniUnregisterDeviceCallbacks(pListener->m_deviceConnectedCallbacksHandle); 02241 pListener->m_deviceConnectedCallbacksHandle = NULL; 02242 } 02250 static void removeDeviceDisconnectedListener(DeviceDisconnectedListener* pListener) 02251 { 02252 oniUnregisterDeviceCallbacks(pListener->m_deviceDisconnectedCallbacksHandle); 02253 pListener->m_deviceDisconnectedCallbacksHandle = NULL; 02254 } 02262 static void removeDeviceStateChangedListener(DeviceStateChangedListener* pListener) 02263 { 02264 oniUnregisterDeviceCallbacks(pListener->m_deviceStateChangedCallbacksHandle); 02265 pListener->m_deviceStateChangedCallbacksHandle = NULL; 02266 } 02267 02276 static Status setLogOutputFolder(const char *strLogOutputFolder) 02277 { 02278 return (Status)oniSetLogOutputFolder(strLogOutputFolder); 02279 } 02280 02290 static Status getLogFileName(char *strFileName, int nBufferSize) 02291 { 02292 return (Status)oniGetLogFileName(strFileName, nBufferSize); 02293 } 02294 02304 static Status setLogMinSeverity(int nMinSeverity) 02305 { 02306 return(Status) oniSetLogMinSeverity(nMinSeverity); 02307 } 02308 02317 static Status setLogConsoleOutput(bool bConsoleOutput) 02318 { 02319 return (Status)oniSetLogConsoleOutput(bConsoleOutput); 02320 } 02321 02330 static Status setLogFileOutput(bool bFileOutput) 02331 { 02332 return (Status)oniSetLogFileOutput(bFileOutput); 02333 } 02334 02335 #if ONI_PLATFORM == ONI_PLATFORM_ANDROID_ARM 02336 02345 static Status setLogAndroidOutput(bool bAndroidOutput) 02346 { 02347 return (Status)oniSetLogAndroidOutput(bAndroidOutput); 02348 } 02349 #endif 02350 02351 private: 02352 OpenNI() 02353 { 02354 } 02355 }; 02356 02392 class CoordinateConverter 02393 { 02394 public: 02405 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, int* pDepthX, int* pDepthY, DepthPixel* pDepthZ) 02406 { 02407 float depthX, depthY, depthZ; 02408 Status rc = (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, &depthX, &depthY, &depthZ); 02409 *pDepthX = (int)depthX; 02410 *pDepthY = (int)depthY; 02411 *pDepthZ = (DepthPixel)depthZ; 02412 return rc; 02413 } 02414 02425 static Status convertWorldToDepth(const VideoStream& depthStream, float worldX, float worldY, float worldZ, float* pDepthX, float* pDepthY, float* pDepthZ) 02426 { 02427 return (Status)oniCoordinateConverterWorldToDepth(depthStream._getHandle(), worldX, worldY, worldZ, pDepthX, pDepthY, pDepthZ); 02428 } 02429 02440 static Status convertDepthToWorld(const VideoStream& depthStream, int depthX, int depthY, DepthPixel depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02441 { 02442 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), float(depthX), float(depthY), float(depthZ), pWorldX, pWorldY, pWorldZ); 02443 } 02444 02455 static Status convertDepthToWorld(const VideoStream& depthStream, float depthX, float depthY, float depthZ, float* pWorldX, float* pWorldY, float* pWorldZ) 02456 { 02457 return (Status)oniCoordinateConverterDepthToWorld(depthStream._getHandle(), depthX, depthY, depthZ, pWorldX, pWorldY, pWorldZ); 02458 } 02459 02471 static Status convertDepthToColor(const VideoStream& depthStream, const VideoStream& colorStream, int depthX, int depthY, DepthPixel depthZ, int* pColorX, int* pColorY) 02472 { 02473 return (Status)oniCoordinateConverterDepthToColor(depthStream._getHandle(), colorStream._getHandle(), depthX, depthY, depthZ, pColorX, pColorY); 02474 } 02475 }; 02476 02491 class Recorder 02492 { 02493 public: 02498 Recorder() : m_recorder(NULL) 02499 { 02500 } 02501 02505 ~Recorder() 02506 { 02507 destroy(); 02508 } 02509 02521 Status create(const char* fileName) 02522 { 02523 if (!isValid()) 02524 { 02525 return (Status)oniCreateRecorder(fileName, &m_recorder); 02526 } 02527 return STATUS_ERROR; 02528 } 02529 02536 bool isValid() const 02537 { 02538 return NULL != getHandle(); 02539 } 02540 02551 Status attach(VideoStream& stream, bool allowLossyCompression = false) 02552 { 02553 if (!isValid() || !stream.isValid()) 02554 { 02555 return STATUS_ERROR; 02556 } 02557 return (Status)oniRecorderAttachStream( 02558 m_recorder, 02559 stream._getHandle(), 02560 allowLossyCompression); 02561 } 02562 02569 Status start() 02570 { 02571 if (!isValid()) 02572 { 02573 return STATUS_ERROR; 02574 } 02575 return (Status)oniRecorderStart(m_recorder); 02576 } 02577 02581 void stop() 02582 { 02583 if (isValid()) 02584 { 02585 oniRecorderStop(m_recorder); 02586 } 02587 } 02588 02592 void destroy() 02593 { 02594 if (isValid()) 02595 { 02596 oniRecorderDestroy(&m_recorder); 02597 } 02598 } 02599 02600 private: 02601 Recorder(const Recorder&); 02602 Recorder& operator=(const Recorder&); 02603 02607 OniRecorderHandle getHandle() const 02608 { 02609 return m_recorder; 02610 } 02611 02612 02613 OniRecorderHandle m_recorder; 02614 }; 02615 02616 // Implemetation 02617 Status VideoStream::create(const Device& device, SensorType sensorType) 02618 { 02619 OniStreamHandle streamHandle; 02620 Status rc = (Status)oniDeviceCreateStream(device._getHandle(), (OniSensorType)sensorType, &streamHandle); 02621 if (rc != STATUS_OK) 02622 { 02623 return rc; 02624 } 02625 02626 m_isOwner = true; 02627 _setHandle(streamHandle); 02628 02629 if (isPropertySupported(STREAM_PROPERTY_AUTO_WHITE_BALANCE) && isPropertySupported(STREAM_PROPERTY_AUTO_EXPOSURE)) 02630 { 02631 m_pCameraSettings = new CameraSettings(this); 02632 } 02633 02634 return STATUS_OK; 02635 } 02636 02637 void VideoStream::destroy() 02638 { 02639 if (!isValid()) 02640 { 02641 return; 02642 } 02643 02644 if (m_pCameraSettings != NULL) 02645 { 02646 delete m_pCameraSettings; 02647 m_pCameraSettings = NULL; 02648 } 02649 02650 if (m_stream != NULL) 02651 { 02652 if(m_isOwner) 02653 oniStreamDestroy(m_stream); 02654 m_stream = NULL; 02655 } 02656 } 02657 02658 Status Device::open(const char* uri) 02659 { 02660 //If we are not the owners, we stick with our own device 02661 if(!m_isOwner) 02662 { 02663 if(isValid()){ 02664 return STATUS_OK; 02665 }else{ 02666 return STATUS_OUT_OF_FLOW; 02667 } 02668 } 02669 02670 OniDeviceHandle deviceHandle; 02671 Status rc = (Status)oniDeviceOpen(uri, &deviceHandle); 02672 if (rc != STATUS_OK) 02673 { 02674 return rc; 02675 } 02676 02677 _setHandle(deviceHandle); 02678 02679 return STATUS_OK; 02680 } 02681 02682 Status Device::_openEx(const char* uri, const char* mode) 02683 { 02684 //If we are not the owners, we stick with our own device 02685 if(!m_isOwner) 02686 { 02687 if(isValid()){ 02688 return STATUS_OK; 02689 }else{ 02690 return STATUS_OUT_OF_FLOW; 02691 } 02692 } 02693 02694 OniDeviceHandle deviceHandle; 02695 Status rc = (Status)oniDeviceOpenEx(uri, mode, &deviceHandle); 02696 if (rc != STATUS_OK) 02697 { 02698 return rc; 02699 } 02700 02701 _setHandle(deviceHandle); 02702 02703 return STATUS_OK; 02704 } 02705 02706 Status Device::_setHandle(OniDeviceHandle deviceHandle) 02707 { 02708 if (m_device == NULL) 02709 { 02710 m_device = deviceHandle; 02711 02712 clearSensors(); 02713 02714 oniDeviceGetInfo(m_device, &m_deviceInfo); 02715 02716 if (isFile()) 02717 { 02718 m_pPlaybackControl = new PlaybackControl(this); 02719 } 02720 02721 // Read deviceInfo 02722 return STATUS_OK; 02723 } 02724 02725 return STATUS_OUT_OF_FLOW; 02726 } 02727 02728 void Device::close() 02729 { 02730 if (m_pPlaybackControl != NULL) 02731 { 02732 delete m_pPlaybackControl; 02733 m_pPlaybackControl = NULL; 02734 } 02735 02736 if (m_device != NULL) 02737 { 02738 if(m_isOwner) 02739 { 02740 oniDeviceClose(m_device); 02741 } 02742 02743 m_device = NULL; 02744 } 02745 } 02746 02747 02748 } 02749 02750 #endif // _OPEN_NI_HPP_
Generated on Tue Nov 12 2013 16:10:45 for OpenNI 2.0 by
