Ios 在ARKit中放置、拖动和删除SCNNodes

Ios 在ARKit中放置、拖动和删除SCNNodes,ios,objective-c,arkit,scnnode,Ios,Objective C,Arkit,Scnnode,我正在用ARKit做一个小项目。我希望能够在点击时将对象添加到我的AR SceneView中,通过双击将其删除,并通过平移或拖动来拖动主题 最初点击以放置对象效果良好,但我在删除节点和拖动时遇到了一些问题 删除和拖动的主要问题是很难实际“按住”或单击SCNNode。大多数结果最终都不在我添加的SCNNode上 第二个问题是拖拽有点麻烦,SCNNode实际上没有我的手指在拖拽时移动那么多 我决定在github上创建一个项目,链接如下: 但我也会在这里发布我的删除对象和拖动对象的代码: -(void

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

最初点击以放置对象效果良好,但我在删除节点和拖动时遇到了一些问题

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

第二个问题是拖拽有点麻烦,SCNNode实际上没有我的手指在拖拽时移动那么多

我决定在github上创建一个项目,链接如下:

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

-(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;
    }
}
所以问题似乎是,我之前没有抓住整个物体,而是抓住了这个物体的一个子物体,当你试图拖动一个子物体时,由于某种原因,它会迫使物体移动缓慢。因此,我不得不做一些尝试和错误,以认识到我必须提高家长级别来解决这个问题


希望这有帮助

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

如果你还没有,你可能想看看苹果的示例项目“在增强现实中放置虚拟对象”,请参阅该项目的url。这肯定涵盖了屏幕上的拖动部分。什么是“移动对象”?我没有看到声明。我正试图在swift中实现这一点,目前为止我已经做到了:@objc func-pangestree(发送方:uipangestrerecognizer){let sceneView=sender.view as!ARSCNView let pannedLocation=sender.location(in:sceneView)let-hitTest=sceneView.hitTest(pannedLocation)if(sender.state==uigestrerecognizerState.start){如果(!hitTest.isEmpty){让sceneHitTestResult=hitTest.first!sceneView.scene.rootNode.chil=sceneHitTestResult.node.parent}movedObject只是一个对SCNNode的引用,该SCNNode在点击时被设置为开始状态,然后在平移手势的状态更改时被更新。它基本上只用于此函数。我使用swift,但请查看我的答案,了解如何拖动具有任意数量子节点的SCNNode。最基本的事情必须是done正在为要选择的对象指定一个
.categoryBitMask
-值,并且仅对具有该位掩码的对象进行hitTest,这样您就不会选择任何不需要的对象。git链接不起作用。请提供代码,以了解对象的放置方式。
-(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;
    }
}