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

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

问题描述

我正在使用ARKit开展一个小项目。我希望能够在点击时将对象添加到我的AR SceneView,用双击删除它们,然后用平移或拖动拖动主题。

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;
    }
}

任何帮助都将受到高度赞赏。

Any help would be highly appreciated.

谢谢。

更新:

所以我发现抓取物品的困难是因为我在使用:
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天全站免登陆