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

Placing, Dragging and Removing SCNNodes in ARKit

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

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

删除和拖动的主要问题是很难实际 'hold' 或单击 SCNNode。大多数结果最终不在我添加的 SCNNode 上。

第二个问题是拖动有点问题,SCNNode 并没有像我的手指在拖动上移动那么多。

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

但我也会 post 我的删除对象和拖动对象的代码在这里:

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

所以问题似乎是我之前没有抓住整个对象,而是仍然抓住了这个对象的子对象,当你试图拖动一个子对象时,由于某种原因它迫使运动变得迟缓。所以我不得不做一些试验和错误来意识到我必须提升父级别来解决这个问题。

希望这对您有所帮助。

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