Commits

Cliff Biffle committed 0c2057e

Added a new Kinect abstraction that uses KVO to distribute new frames. Not sure if this is a great idea yet, but giving it a shot!

Comments (0)

Files changed (4)

+/*
+ * Copyright 2010 Cliff L. Biffle.  All Rights Reserved.
+ * Use of this source code is governed by the Apache License 2.0,
+ * which can be found in the LICENSE file.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+// Collects and broadcasts depth and color information.  Depth and
+// color may be generated asynchronously.
+@protocol KVDataSource <NSObject>
+
+- (void)open;
+
+// The latest frame of depth samples, in the Kinect's format: 12-bit
+// samples in 16-bit fields, organized as 480 rows of 640 samples.
+@property (readonly) NSData *latestDepthSamples;
+
+// The latest frame of color samples, as 480 rows of 640 samples of
+// 24-bit RGB.
+@property (readonly) NSData *latestColorSamples;
+
+- (void)close;
+
+@end

KVKinectHardware.h

+/*
+ * Copyright 2010 Cliff L. Biffle.  All Rights Reserved.
+ * Use of this source code is governed by the Apache License 2.0,
+ * which can be found in the LICENSE file.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "KVDataSource.h"
+#import "libfreenect.h"
+
+@interface KVKinectHardware : NSObject <KVDataSource> {
+  freenect_context *context;
+  freenect_device *device;
+	
+  BOOL running;  
+}
+
+@end

KVKinectHardware.m

+/*
+ * Copyright 2010 Cliff L. Biffle.  All Rights Reserved.
+ * Use of this source code is governed by the Apache License 2.0,
+ * which can be found in the LICENSE file.
+ */
+
+#import "KVKinectHardware.h"
+#import <pthread.h>
+#import "libfreenect.h"
+
+@interface KVKinectHardware ()
+- (void)ioThread;
+
+@property (assign) NSData *latestDepthSamples;
+@property (assign) NSData *latestColorSamples;
+@end
+
+static void depthCallback(freenect_device *dev, freenect_depth *depth, uint32_t timestamp) {
+  ((KVKinectHardware *)freenect_get_user(dev)).latestDepthSamples = [NSData dataWithBytesNoCopy: depth length: sizeof *depth freeWhenDone: NO];
+}
+static void rgbCallback(freenect_device *dev, freenect_pixel *rgb, uint32_t timestamp) {
+  ((KVKinectHardware *)freenect_get_user(dev)).latestColorSamples = [NSData dataWithBytesNoCopy: rgb length: sizeof *rgb freeWhenDone: NO];
+}
+
+@implementation KVKinectHardware
+
+@synthesize latestDepthSamples, latestColorSamples;
+
+- (void)open {
+ 	[NSThread detachNewThreadSelector:@selector(ioThread) toTarget:self withObject:nil]; 
+}
+
+- (void)close {
+  running = NO;
+}
+
+- (void)ioThread
+{
+  [[NSThread currentThread] setName: @"kinect-io-thread"];
+  pthread_setname_np("kinect-io-thread");
+	if(freenect_init(&context, NULL) >= 0) {
+    if(freenect_open_device(context, &device, 0) >= 0) {
+      freenect_set_user(device, self);
+      freenect_set_depth_callback(device, depthCallback);
+      freenect_set_rgb_callback(device, rgbCallback);
+      freenect_set_rgb_format(device, FREENECT_FORMAT_RGB);
+      freenect_set_depth_format(device, FREENECT_FORMAT_11_BIT);
+      freenect_start_depth(device);
+      freenect_start_rgb(device);
+      
+      NSLog(@"wheeee");
+      
+      while(running && freenect_process_events(context) >= 0);
+      
+      freenect_close_device(device);
+      device = NULL;
+      
+      NSLog(@"Stopped");
+    } else {
+      NSLog(@"Could not open device");
+    }
+    freenect_shutdown(context);
+    context = NULL;
+  } else {
+		NSLog(@"Could not init device");
+	}
+}
+
+@end

KinectViewer.xcodeproj/project.pbxproj

 		C70E66BB129C906C004A44B3 /* libdriver.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C70E669F129C9005004A44B3 /* libdriver.a */; };
 		C70E66CA129C9121004A44B3 /* libusb-1.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C70E66C9129C9121004A44B3 /* libusb-1.0.dylib */; };
 		C758083412A4C46700391C33 /* KVRayFieldSpaceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C758083312A4C46700391C33 /* KVRayFieldSpaceModel.m */; };
+		C7759B4612A8B2D3003479EF /* KVKinectHardware.m in Sources */ = {isa = PBXBuildFile; fileRef = C7759B4512A8B2D3003479EF /* KVKinectHardware.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
 		C758081A12A4C22400391C33 /* KVSpaceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KVSpaceModel.h; sourceTree = "<group>"; };
 		C758083212A4C46700391C33 /* KVRayFieldSpaceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KVRayFieldSpaceModel.h; sourceTree = "<group>"; };
 		C758083312A4C46700391C33 /* KVRayFieldSpaceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KVRayFieldSpaceModel.m; sourceTree = "<group>"; };
+		C7759B3F12A8B1EB003479EF /* KVDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KVDataSource.h; sourceTree = "<group>"; };
+		C7759B4412A8B2D3003479EF /* KVKinectHardware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KVKinectHardware.h; sourceTree = "<group>"; };
+		C7759B4512A8B2D3003479EF /* KVKinectHardware.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KVKinectHardware.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 		C7F36B8812A19EBD00EBC3AB /* Model */ = {
 			isa = PBXGroup;
 			children = (
+				C7759B3F12A8B1EB003479EF /* KVDataSource.h */,
+				C7759B4412A8B2D3003479EF /* KVKinectHardware.h */,
+				C7759B4512A8B2D3003479EF /* KVKinectHardware.m */,
 				C758081A12A4C22400391C33 /* KVSpaceModel.h */,
 				C758083212A4C46700391C33 /* KVRayFieldSpaceModel.h */,
 				C758083312A4C46700391C33 /* KVRayFieldSpaceModel.m */,
 				C70E635F129C63BE004A44B3 /* trackball.c in Sources */,
 				C70E6691129C8FD5004A44B3 /* KFKinect.m in Sources */,
 				C758083412A4C46700391C33 /* KVRayFieldSpaceModel.m in Sources */,
+				C7759B4612A8B2D3003479EF /* KVKinectHardware.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};