首页 文章

在 ARKit 中放置,拖动和删除 SCNNode

提问于
浏览
5

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

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

删除和拖动的主要问题是实际上“保持”或单击 SCNNode 非常困难。大多数结果都没有出现在我添加的 SCNNode 上。

第二个问题是拖动有点儿错误,SCNNode 实际上并没有像我的手指那样在拖动上移动。

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

但我也会发布我的代码来删除对象并拖动对象:

-(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;当我试图点击一个物体时,它大部分时间都会抓住其中一个特征点。

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

所以这个问题似乎不是以前抓住整个物体,而是还抓住了这个物体的孩子,当你试图拖动一个孩子时,由于某种原因它迫使运动变得迟钝。所以我不得不做一些试验和错误才意识到我必须提升父级才能解决问题。

希望这可以帮助。

1 回答

  • 0

    拖动对象的解决方案是将 movedObject 设置为[[[[1] parentNode] parentNode] parentNode],拖动变得更加平滑。

相关问题