PolycodeKinect.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * PolycodeKinect.cpp
  3. * PolycodeKinectTest
  4. *
  5. * Created by Ivan Safrin on 12/2/10.
  6. * Copyright 2010 Local Projects. All rights reserved.
  7. *
  8. */
  9. #include "PolycodeKinect.h"
  10. using namespace Polycode;
  11. PolycodeRunner *polycodeRunner;
  12. pthread_mutex_t gl_backbuf_mutex = PTHREAD_MUTEX_INITIALIZER;
  13. pthread_mutex_t usbMutex = PTHREAD_MUTEX_INITIALIZER;
  14. PolycodeRunner::PolycodeRunner() : Threaded() {
  15. polycodeRunner = this;
  16. current_format = FREENECT_VIDEO_RGB;
  17. requested_format = FREENECT_VIDEO_RGB;
  18. freenect_angle = 0;
  19. depth_mid = (uint8_t*)malloc(640*480*3);
  20. depth_front = (uint8_t*)malloc(640*480*3);
  21. rgb_back = (uint8_t*)malloc(640*480*3);
  22. rgb_mid = (uint8_t*)malloc(640*480*3);
  23. rgb_front = (uint8_t*)malloc(640*480*3);
  24. int i;
  25. for (i=0; i<2048; i++) {
  26. float v = i/2048.0;
  27. v = powf(v, 3)* 5;
  28. t_gamma[i] = v*6*256;
  29. }
  30. initKinect();
  31. }
  32. int PolycodeRunner::initKinect() {
  33. if (freenect_init(&f_ctx, NULL) < 0) {
  34. printf("freenect_init() failed\n");
  35. return 0;
  36. }
  37. freenect_set_log_level(f_ctx, FREENECT_LOG_FATAL);
  38. int nr_devices = freenect_num_devices (f_ctx);
  39. printf ("Number of devices found: %d\n", nr_devices);
  40. if (freenect_open_device(f_ctx, &f_dev, 0) < 0) {
  41. printf("Could not open device\n");
  42. return 1;
  43. }
  44. return 1;
  45. }
  46. PolycodeRunner::~PolycodeRunner() {
  47. }
  48. void PolycodeRunner::runThread() {
  49. freenect_set_tilt_degs(f_dev,freenect_angle);
  50. freenect_set_led(f_dev,LED_BLINK_YELLOW);
  51. freenect_set_depth_callback(f_dev, depth_cb);
  52. freenect_set_video_callback(f_dev, rgb_cb);
  53. freenect_set_video_format(f_dev, current_format);
  54. freenect_set_depth_format(f_dev, FREENECT_DEPTH_11BIT);
  55. freenect_set_video_buffer(f_dev, rgb_back);
  56. freenect_start_depth(f_dev);
  57. freenect_start_video(f_dev);
  58. while (threadRunning && freenect_process_events(f_ctx) >= 0) {
  59. pthread_mutex_lock(&usbMutex);
  60. freenect_raw_tilt_state* state;
  61. freenect_update_tilt_state(f_dev);
  62. state = freenect_get_tilt_state(f_dev);
  63. double dx,dy,dz;
  64. freenect_get_mks_accel(state, &dx, &dy, &dz);
  65. printf("\r raw acceleration: %4d %4d %4d mks acceleration: %4f %4f %4f", state->accelerometer_x, state->accelerometer_y, state->accelerometer_z, dx, dy, dz);
  66. fflush(stdout);
  67. if (requested_format != current_format) {
  68. freenect_stop_video(f_dev);
  69. freenect_set_video_format(f_dev, requested_format);
  70. freenect_start_video(f_dev);
  71. current_format = requested_format;
  72. }
  73. pthread_mutex_unlock(&usbMutex);
  74. }
  75. printf("\nshutting down streams...\n");
  76. printf("Cleaning freenect...\n");
  77. free(depth_mid);
  78. free(depth_front);
  79. free(rgb_back);
  80. free(rgb_mid);
  81. free(rgb_front);
  82. freenect_stop_depth(f_dev);
  83. freenect_stop_video(f_dev);
  84. freenect_close_device(f_dev);
  85. freenect_shutdown(f_ctx);
  86. }
  87. void PolycodeRunner::rgbCallback(freenect_device *dev, void *rgb, uint32_t timestamp) {
  88. rgb_back = rgb_mid;
  89. freenect_set_video_buffer(dev, rgb_back);
  90. rgb_mid = (uint8_t*)rgb;
  91. }
  92. void PolycodeRunner::depthCallback(freenect_device *dev, void *v_depth, uint32_t timestamp) {
  93. int i;
  94. uint16_t *depth = (uint16_t*)v_depth;
  95. // pthread_mutex_lock(&gl_backbuf_mutex);
  96. for (i=0; i<FREENECT_FRAME_PIX; i++) {
  97. int pval = t_gamma[depth[i]];
  98. int lb = pval & 0xff;
  99. /*
  100. if(pval>>8 == 0) {
  101. depth_mid[3*i+0] = 255-lb;
  102. depth_mid[3*i+1] = 255-lb;
  103. depth_mid[3*i+2] = 255-lb;
  104. } else {
  105. depth_mid[3*i+0] = 0;
  106. depth_mid[3*i+1] = 0;
  107. depth_mid[3*i+2] = 0;
  108. }
  109. */
  110. switch (pval>>8) {
  111. case 0:
  112. depth_mid[3*i+0] = 255;
  113. depth_mid[3*i+1] = 255-lb;
  114. depth_mid[3*i+2] = 255-lb;
  115. break;
  116. case 1:
  117. depth_mid[3*i+0] = 255;
  118. depth_mid[3*i+1] = lb;
  119. depth_mid[3*i+2] = 0;
  120. break;
  121. case 2:
  122. depth_mid[3*i+0] = 255-lb;
  123. depth_mid[3*i+1] = 255;
  124. depth_mid[3*i+2] = 0;
  125. break;
  126. case 3:
  127. depth_mid[3*i+0] = 0;
  128. depth_mid[3*i+1] = 255;
  129. depth_mid[3*i+2] = lb;
  130. break;
  131. case 4:
  132. depth_mid[3*i+0] = 0;
  133. depth_mid[3*i+1] = 255-lb;
  134. depth_mid[3*i+2] = 255;
  135. break;
  136. case 5:
  137. depth_mid[3*i+0] = 0;
  138. depth_mid[3*i+1] = 0;
  139. depth_mid[3*i+2] = 255-lb;
  140. break;
  141. default:
  142. depth_mid[3*i+0] = 0;
  143. depth_mid[3*i+1] = 0;
  144. depth_mid[3*i+2] = 0;
  145. break;
  146. }
  147. /*
  148. case 0:
  149. depth_mid[3*i+0] = 255;
  150. depth_mid[3*i+1] = 255;
  151. depth_mid[3*i+2] = 255;
  152. break;
  153. case 1:
  154. depth_mid[3*i+0] = 0;
  155. depth_mid[3*i+1] = 0;
  156. depth_mid[3*i+2] = 0;
  157. break;
  158. case 2:
  159. depth_mid[3*i+0] = 0;
  160. depth_mid[3*i+1] = 0;
  161. depth_mid[3*i+2] = 0;
  162. break;
  163. case 3:
  164. depth_mid[3*i+0] = 0;
  165. depth_mid[3*i+1] = 0;
  166. depth_mid[3*i+2] = 0;
  167. break;
  168. case 4:
  169. depth_mid[3*i+0] = 0;
  170. depth_mid[3*i+1] = 0;
  171. depth_mid[3*i+2] = 0;
  172. break;
  173. case 5:
  174. depth_mid[3*i+0] = 0;
  175. depth_mid[3*i+1] = 0;
  176. depth_mid[3*i+2] = 0;
  177. break;
  178. default:
  179. depth_mid[3*i+0] = 0;
  180. depth_mid[3*i+1] = 0;
  181. depth_mid[3*i+2] = 0;
  182. break;
  183. }
  184. */
  185. }
  186. }
  187. void depth_cb(freenect_device *dev, void *v_depth, uint32_t timestamp) {
  188. pthread_mutex_lock(&gl_backbuf_mutex);
  189. polycodeRunner->depthCallback(dev, v_depth, timestamp);
  190. pthread_mutex_unlock(&gl_backbuf_mutex);
  191. }
  192. void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp) {
  193. pthread_mutex_lock(&gl_backbuf_mutex);
  194. polycodeRunner->rgbCallback(dev, rgb, timestamp);
  195. pthread_mutex_unlock(&gl_backbuf_mutex);
  196. }
  197. void PolycodeRunner::tiltUp() {
  198. pthread_mutex_lock(&usbMutex);
  199. freenect_angle++;
  200. if (freenect_angle > 30) {
  201. freenect_angle = 30;
  202. }
  203. freenect_set_tilt_degs(f_dev,freenect_angle);
  204. pthread_mutex_unlock(&usbMutex);
  205. }
  206. void PolycodeRunner::tiltDown() {
  207. pthread_mutex_lock(&usbMutex);
  208. freenect_angle--;
  209. if (freenect_angle < -30) {
  210. freenect_angle = -30;
  211. }
  212. freenect_set_tilt_degs(f_dev,freenect_angle);
  213. pthread_mutex_unlock(&usbMutex);
  214. }
  215. void PolycodeRunner::Level() {
  216. pthread_mutex_lock(&usbMutex);
  217. freenect_angle = 0;
  218. freenect_set_tilt_degs(f_dev,freenect_angle);
  219. pthread_mutex_unlock(&usbMutex);
  220. }
  221. PolycodeKinect::PolycodeKinect(bool calculatePoints) : EventHandler() {
  222. this->calculatePoints = calculatePoints;
  223. this->calculateColors = true;
  224. rgbTexture = NULL;
  225. updateTimer = new Timer(true, 10);
  226. updateTimer->addEventListener(this, Timer::EVENT_TRIGGER);
  227. runner = new PolycodeRunner();
  228. rgbPtr = runner->rgb_front;
  229. rgbTexture = CoreServices::getInstance()->getMaterialManager()->createTexture(640, 480, (char*)runner->rgb_front, false, Image::IMAGE_RGB);
  230. closeDepthTexture = CoreServices::getInstance()->getMaterialManager()->createTexture(640, 480, (char*)runner->depth_mid, false, Image::IMAGE_RGB);
  231. CoreServices::getInstance()->getCore()->createThread(runner);
  232. }
  233. void PolycodeKinect::handleEvent(Event *event) {
  234. if(event->getDispatcher() == updateTimer) {
  235. Image *newImage = new Image((char*)runner->rgb_back, 640, 480, Image::IMAGE_RGB);
  236. rgbTexture->setImageData(newImage);
  237. rgbTexture->recreateFromImageData();
  238. delete newImage;
  239. newImage = new Image((char*)runner->depth_mid, 640, 480, Image::IMAGE_RGB);
  240. closeDepthTexture->setImageData(newImage);
  241. closeDepthTexture->recreateFromImageData();
  242. delete newImage;
  243. if(calculatePoints || calculateColors) {
  244. for(int i=0; i < MAX_KINECT_POINTS; i++) {
  245. points[i] = Vector3(0,0,0);
  246. colors[i].setColorRGB(0,0,0);
  247. }
  248. int ptIndex = 0;
  249. char *data = closeDepthTexture->getTextureData();
  250. char *colorData = rgbTexture->getTextureData();
  251. for(int y=0; y < 480; y+= 7) {
  252. for(int x=0; x < 640; x += 7) {
  253. char *testArr = data + ((x*3)+(y*640*3));
  254. unsigned int testArrColor = *((unsigned int*) (colorData + ((x-30)*3)+((y+30)*640*3)));
  255. if(testArr[1] > 0) {
  256. if(ptIndex < MAX_KINECT_POINTS) {
  257. if(calculateColors) {
  258. colors[ptIndex].setColorHexRGB(testArrColor);
  259. }
  260. if(calculatePoints) {
  261. points[ptIndex] = Vector3(x, y, testArr[1]);
  262. }
  263. ptIndex++;
  264. } else {
  265. return;
  266. }
  267. }
  268. }
  269. }
  270. }
  271. }
  272. }
  273. void PolycodeKinect::tiltUp() {
  274. runner->tiltUp();
  275. }
  276. void PolycodeKinect::tiltDown() {
  277. runner->tiltDown();
  278. }
  279. void PolycodeKinect::Level() {
  280. runner->Level();
  281. }
  282. Texture *PolycodeKinect::getCloseDepthTexture() {
  283. return closeDepthTexture;
  284. }
  285. Texture *PolycodeKinect::getRGBTexture() {
  286. return rgbTexture;
  287. }
  288. PolycodeKinect::~PolycodeKinect() {
  289. printf("Cleaning kinect\n");
  290. runner->killThread();
  291. }