在 ARKit 中放置、拖动和移除 SCNNode [英] Placing, Dragging and Removing SCNNodes in ARKit

查看:46
本文介绍了在 ARKit 中放置、拖动和移除 SCNNode的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ARKit 进行一个小项目.我希望能够在点击时将对象添加到我的 AR 场景视图中,双击删除它们,然后通过平移或拖动来拖动主题.

I'm working on a small project using ARKit. I want to be able to add objects to my AR SceneView on tap, remove them with a double tap, and drag theme around with a pan or drag.

放置对象的初始点击工作正常,但我在删除节点和拖动时遇到了一些问题.

The initial tap to place objects is working fine, but I have some issues with the Node removal and the dragging.

移除和拖动的主要问题是很难真正按住"或点击 SCNNode.大多数结果最终不在我添加的 SCNNode 上.

The main issue with the removal and the dragging is that it is very difficult to actually 'hold' or click on the SCNNode. Most of the results end up not being on the SCNNode I've added.

第二个问题是拖动有点问题,SCNNode 并没有像我的手指那样移动.

The second issue is that the dragging is a bit buggy, the SCNNode doesn't really move as much as my finger does on the drag.

我决定在github上创建一个项目,链接在这里:https://github.com/theraad/ARAttempt

I've decided to create a project on github, which is linked here: https://github.com/theraad/ARAttempt

但我也会在此处发布用于删除对象和拖动对象的代码:

But I'll also post my code for removing objects and dragging objects here:

-(void)handleRemoveObject:(UITapGestureRecognizer *)recognizer {
    NSLog(@"Long Press Fired");
    CGPoint tapPoint = [recognizer locationInView:_sceneView];

    NSArray <SCNHitTestResult *> *result = [self.sceneView hitTest:tapPoint options:nil];

    if ([result count] == 0) {
        return;
    }
    SCNHitTestResult *hitResult = [result firstObject];
    if (hitResult.node) {
        [[hitResult.node parentNode] removeFromParentNode];
    }
}

-(void)moveObject:(UIPanGestureRecognizer *)recognizer {
    NSLog(@"Move object");
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Pan state began");
        CGPoint tapPoint = [recognizer locationInView:_sceneView];
        NSArray <SCNHitTestResult *> *result = [self.sceneView hitTest:tapPoint options:nil];

        if ([result count] == 0) {
            return;
        }
        SCNHitTestResult *hitResult = [result firstObject];
        if ([hitResult.node.name isEqualToString:@"candle"]) {
            movedObject = [hitResult node];
        } else if ([[hitResult.node parentNode].name isEqualToString:@"candle"]) {
            movedObject = [[[hitResult node] parentNode] parentNode] parentNode];
        }
        if (movedObject){
            NSLog(@"Holding an Object");
        }
    }
    if (recognizer.state == UIGestureRecognizerStateChanged) {
        NSLog(@"Pan State Changed");
        if (movedObject) {

            CGPoint tapPoint = [recognizer locationInView:_sceneView];
            NSArray <ARHitTestResult *> *hitResults = [_sceneView hitTest:tapPoint types:ARHitTestResultTypeFeaturePoint];
            ARHitTestResult *result = [hitResults lastObject];

            SCNMatrix4 matrix = SCNMatrix4FromMat4(result.worldTransform);
            SCNVector3 vector = SCNVector3Make(matrix.m41, matrix.m42, matrix.m43);

            [movedObject setPosition:vector];
            NSLog(@"Moving object position");
        }
    }
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Done moving object homeie");
        movedObject = nil;
    }
}

任何帮助将不胜感激.

谢谢.

更新:

所以我发现抓取物体的困难是因为我使用了:self.sceneView.debugOptions = ARSCNDebugOptionShowFeaturePoints;当我尝试点击一个对象时,大多数时候它会抓住这些特征点之一.

So I found out that the difficulty with grabbing objects was because I was using: self.sceneView.debugOptions = ARSCNDebugOptionShowFeaturePoints; And when i would try to click on an object, it would most of the times be grabbing one of these feature points.

-(void)moveObject:(UIPanGestureRecognizer *)recognizer {
    NSLog(@"Move object");
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Pan state began");
        CGPoint tapPoint = [recognizer locationInView:_sceneView];
        NSArray <SCNHitTestResult *> *result = [self.sceneView hitTest:tapPoint options:nil];

        if ([result count] == 0) {
            return;
        }
        SCNHitTestResult *hitResult = [result firstObject];
        movedObject = [[[hitResult node] parentNode] parentNode] parentNode]; //This aspect varies based on the type of .SCN file that you have
        }
        if (movedObject){
            NSLog(@"Holding an Object");
        }
    }
    if (recognizer.state == UIGestureRecognizerStateChanged) {
        NSLog(@"Pan State Changed");
        if (movedObject) {

            CGPoint tapPoint = [recognizer locationInView:_sceneView];
            NSArray <ARHitTestResult *> *hitResults = [_sceneView hitTest:tapPoint types:ARHitTestResultTypeFeaturePoint];
            ARHitTestResult *result = [hitResults lastObject];

            SCNMatrix4 matrix = SCNMatrix4FromMat4(result.worldTransform);
            SCNVector3 vector = SCNVector3Make(matrix.m41, matrix.m42, matrix.m43);

            [movedObject setPosition:vector];
            NSLog(@"Moving object position");
        }
    }
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Done moving object homeie");
        movedObject = nil;
    }
}

所以问题似乎是,我之前没有抓取整个对象,而是抓取了这个对象的一个​​孩子,当你试图拖动一个孩子时,它会由于某种原因迫使运动变得迟缓.所以我不得不做一些反复试验才能意识到我必须提升父母级别才能解决这个问题.

So the issue seems that instead of grabbing the whole object previously, I was still grabbing a child of this object, and when you attempt to drag a child it forces the movement to be laggy for some reason. So I had to do a bit of trial and error to realize that I had to move up parent levels to fix the issue.

希望这会有所帮助.

推荐答案

拖动对象的解决方案是将movedObject设置为[[[hitResult node] parentNode] parentNode] parentNode],拖动变得更流畅.

The solution for dragging the object was to set the movedObject to the [[[hitResult node] parentNode] parentNode] parentNode] and the drag became smoother.

这篇关于在 ARKit 中放置、拖动和移除 SCNNode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆