Objective c 如何将Leap运动控制器集成到Mac应用程序中?

Objective c 如何将Leap运动控制器集成到Mac应用程序中?,objective-c,macos,leap-motion,Objective C,Macos,Leap Motion,我正试图在Mac上启动我自己的Leap Motion项目,但我遇到了一些问题 我想在这个项目中使用Objective-C,并且我已经读到有一个用于这种语言的Leap Motion库。但是,我不知道如何使用这个库将Leap运动控件集成到Mac应用程序中 有人问了一些类似的问题,只是他们问的是使用Python Leap运动库 如何将跳跃运动控件添加到Objective-C Mac应用程序中?我最近做了这件事,因此我可以提供将跳跃运动控件添加到Mac应用程序中的步骤。事实上,我的Leap-enable

我正试图在Mac上启动我自己的Leap Motion项目,但我遇到了一些问题

我想在这个项目中使用Objective-C,并且我已经读到有一个用于这种语言的Leap Motion库。但是,我不知道如何使用这个库将Leap运动控件集成到Mac应用程序中

有人问了一些类似的问题,只是他们问的是使用Python Leap运动库


如何将跳跃运动控件添加到Objective-C Mac应用程序中?

我最近做了这件事,因此我可以提供将跳跃运动控件添加到Mac应用程序中的步骤。事实上,我的Leap-enabled分子应用程序的源代码是,如果您想从中获得一个示例的话。您只需构建Leap SDK即可

跳跃动作Objto-C标题基本上是围绕其底层C++ API的包装,但是你不需要关心,因为你可以通过Objut-C.< 要将库添加到项目中,请首先在系统中的某个位置安装Leap SDK。从那里,添加对项目中

Leap.h
LeapMath.h
LeapObjectiveC.h
LeapObjectiveC.mm
文件的引用。将
libLeap.dylib
库添加到链接库中

为了避免测试期间出现编译器和链接器错误(可能已经解决),我需要转到构建设置并将
C++标准库
更改为
libstdc++

您需要确保Leap库与应用程序捆绑在一起,因此确保在构建阶段将其复制到捆绑的框架中。我还需要使用以下运行脚本构建阶段来确保其内部路径设置正确(同样,现在不确定是否需要):

设置此设置时的最后一个警告是,如果要对Mac应用程序进行沙箱处理,则需要启用传出网络连接权限,否则应用程序将无法连接到Mac上运行的Leap Motion server应用程序

完成所有设置后,您可以开始从Leap Motion控制器获取输入。中央LeapController对象将为Leap运动事件提供代理回调。您可以使用如下代码设置一个:

controller = [[LeapController alloc] init];
[controller addListener:self];
LeapController *aController = (LeapController *)[notification object];
LeapFrame *frame = [aController frame:0];
您的代理需要满足LeapListener协议,该协议有一系列可选的回调方法:

// Controller object has initialized
- (void)onInit:(NSNotification *)notification
// Controller has connected
- (void)onConnect:(NSNotification *)notification;
// Controller has disconnected
- (void)onDisconnect:(NSNotification *)notification;
// Exiting your LeapController object
- (void)onExit:(NSNotification *)notification;
// New frame data has arrived from the controller
- (void)onFrame:(NSNotification *)notification;
连接和断开回调是显而易见的,不过您会注意到,在Xcode中调试应用程序时,断开回调从未被触发。您需要在调试器之外运行应用程序,以便在断开Leap Motion控制器时触发调试器

您将在
-onFrame:
回调中花费大部分时间,因为这是您获得定位更新的地方。您可以从中获取LeapController作为通知对象,并且可以使用以下方法提取当前帧数据:

controller = [[LeapController alloc] init];
[controller addListener:self];
LeapController *aController = (LeapController *)[notification object];
LeapFrame *frame = [aController frame:0];
LeapFrame中包含Leap观察到的所有场景数据,包括手和手指位置以及这些位置的整体缩放。LeapFrame上的
-hands
方法提供所有检测到的LeapHand对象的数组。反过来,您可以通过其
-fingers
方法获得LeapHand的每个LeapFinger。您还可以提取手的
手掌位置
手掌法线
,以及整个
方向

方向以跳跃向量的形式提供,跳跃向量是围绕三维向量的包装对象。可以从中提取X、Y和Z分量,或执行向量操作或其他向量之间的比较

在分子中,我通过读取屏幕上的进出或从左到右的运动来调整分子结构的大小和方向。我通过比较一只张开的手从一帧到下一帧的位置来做到这一点。我存储了前一帧,然后将现在和上次看到这只手使用

LeapVector *handTranslation = [firstHand translation:previousLeapFrame];
您还可以将手或帧中所有对象作为一个组在帧之间比较缩放、旋转等。从我在上述代码中获得的帧到帧的转换中,我可以提取单独的X、Y和Z分量来旋转模型,以响应X和Y的转换和基于Z的缩放


我在应用程序中使用粗略定位,但通过跟踪单个指尖显然可以做得更好。在安装应用程序并使用设备运行之后,我建议您阅读Objective-C端的Leap SDK头文件,以了解您还可以使用哪些其他功能。另外,尝试不同的交互模式,因为你可能会惊讶于什么在三维空间中工作得好,什么不好。

@Brad Larson的答案几乎涵盖了所有内容,所以请参考它了解更多细节。但是,他的回答说明了如何使用LeapListener协议,该协议使用NSNotifications

如果您不喜欢NSNotificationCenter:p,或者不关心更新发生在哪个线程上,下面是一个如何使用
LeapDelegate
的示例

@interface MyClass () < LeapDelegate >
@property (strong, nonatomic) LeapController *controller;
@end



- (void)startLeapMotion
{
    if (!_controller) {
        _controller = [[LeapController alloc] initWithDelegate:self];
//
//    Could also be...
//
//    [_controller addDelegate:self];
//    [_controller removeDelegate];
    }
}


- (void)onInit:(LeapController *)controller
{
    NSLog(@"Init");
}

- (void)onConnect:(LeapController *)controller
{
    NSLog(@"Connect");

//    Some settings that came bundled with the Leap sample project. Use if needed
//
//    [controller setPolicyFlags:LEAP_POLICY_DEFAULT];
//    [controller enableGesture:LEAP_GESTURE_TYPE_CIRCLE enable:YES];
//    [controller enableGesture:LEAP_GESTURE_TYPE_KEY_TAP enable:YES];
//    [controller enableGesture:LEAP_GESTURE_TYPE_SCREEN_TAP enable:YES];
//    [controller enableGesture:LEAP_GESTURE_TYPE_SWIPE enable:YES];
}

- (void)onFocusGained:(LeapController *)controller
{
    NSLog(@"Focus Gained");
}

- (void)onFrame:(LeapController *)controller
{
// Write awesome code here!!!
    NSLog(@"Frame");
}

- (void)onFocusLost:(LeapController *)controller
{
    NSLog(@"Focus Lost");
}

- (void)onDisconnect:(LeapController *)controller
{
    NSLog(@"Disconnected");
}

- (void)onExit:(LeapController *)controller
{
    NSLog(@"Exited");
}
@interface MyClass()
@属性(强,非原子)LeapController*控制器;
@结束
-(无效)动议
{
如果(!\u控制器){
_控制器=[[LeapController alloc]initWithDelegate:self];
//
//也可能是。。。
//
//[_controlleradddelegate:self];
//[_控制器已卸下电子门];
}
}
-(void)onInit:(LeapController*)控制器
{
NSLog(@“Init”);
}
-(void)onConnect:(LeapController*)控制器
{
NSLog(@“连接”);
//Leap示例项目附带的一些设置。如果需要,请使用
//
//[控制器setPolicyFlags:LEAP_POLICY_DEFAULT];
//[控制器启用手势:跳跃手势\类型\圆圈启用:是];
//[控制器启用手势:跳跃\u手势\u类型\u键\u点击启用: