Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用手势在ARSCNView中移动SCNNode_Objective C_Swift_Augmented Reality_Arkit_Uipangesturerecognizer - Fatal编程技术网

Objective c 使用手势在ARSCNView中移动SCNNode

Objective c 使用手势在ARSCNView中移动SCNNode,objective-c,swift,augmented-reality,arkit,uipangesturerecognizer,Objective C,Swift,Augmented Reality,Arkit,Uipangesturerecognizer,我一直在尝试使用UIPangestureRecognitor在iOS ARKit中移动连接到UISceneView的SCNNode。它在x维度上移动得很好,但我似乎不知道如何在y方向上移动它。我采用了两种不同的方法,每种方法都没有成功: 任何关于为什么y维度的行为似乎与x维度的行为不一样的见解都将不胜感激。这可能只与XZ平面上的运动有关吗?下面是上面#2中引用的GitHub示例代码之后的代码: ============== //移动SCN节点 -(无效)handlePanGesture:(U

我一直在尝试使用UIPangestureRecognitor在iOS ARKit中移动连接到UISceneView的SCNNode。它在x维度上移动得很好,但我似乎不知道如何在y方向上移动它。我采用了两种不同的方法,每种方法都没有成功:

  • 任何关于为什么y维度的行为似乎与x维度的行为不一样的见解都将不胜感激。这可能只与XZ平面上的运动有关吗?下面是上面#2中引用的GitHub示例代码之后的代码:

    ==============

    //移动SCN节点 -(无效)handlePanGesture:(UIPangestureRecognitor*)页码 {

    }

    下面是输出控制台的片段。请注意,计算的“dx”始终为.000000

    [CalibrationController handlePanGesture:] tapPoint  {207.33332824707031, 507}
    
    [CalibrationController handlePanGesture:] lastVector: x = -0.016018, y = -0.083625, z = 0.006696
    
    [CalibrationController handlePanGesture:] newVector: x = -0.015562, y = -0.083862, z = 0.006658
    
    [CalibrationController handlePanGesture:] dx = 0.000456, dy = **-0.000237**
    
    [CalibrationController handlePanGesture:] gypsyTargetNode.position: x = -0.018142, y = -0.087894, z = 0.008041
    
    [CalibrationController handlePanGesture:] hitResults.count: 2
    
    [CalibrationController handlePanGesture:] lastVector: x = -0.015562, y = -0.083862, z = 0.006658
    
    [CalibrationController handlePanGesture:] newVector: x = -0.015562, y = -0.083862, z = 0.006658
    
    [CalibrationController handlePanGesture:] dx = 0.000000, dy = **0.000000**
    
    [CalibrationController handlePanGesture:] gypsyTargetNode.position: x = -0.018142, y = -0.087894, z = 0.008041
    
    [CalibrationController handlePanGesture:] hitResults.count: 2
    
    [CalibrationController handlePanGesture:] lastVector: x = -0.015562, y = -0.083862, z = 0.006658
    
    [CalibrationController handlePanGesture:] newVector: x = -0.015150, y = -0.083862, z = 0.006565
    
    [CalibrationController handlePanGesture:] dx = 0.000412, dy = **0.000000**
    
    [CalibrationController handlePanGesture:] gypsyTargetNode.position: x = -0.017730, y = -0.087894, z = 0.008041
    
    [CalibrationController handlePanGesture:] hitResults.count: 2
    
    [CalibrationController handlePanGesture:] lastVector: x = -0.015150, y = -0.083862, z = 0.006565
    
    [CalibrationController handlePanGesture:] newVector: x = -0.014686, y = -0.083862, z = 0.006361
    
    [CalibrationController handlePanGesture:] dx = 0.000463, dy = **0.000000**
    

    对于平移手势,请执行以下方法:

    let myScene = SCNScene(named: "scene.scn")!
    let modelNode: SCNNode = myScene.rootNode
    var selectedNode: SCNNode? = nil
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let moveGesture = UIPanGestureRecognizer(target: self, 
                                                 action: #selector(moveModel))
    
        self.sceneView.addGestureRecognizer(moveGesture)
    }
    
    检查重要条件(如有):

    private func myMethod(at position: CGPoint) -> SCNNode? {
    
        let nnn = self.sceneView.hitTest(position, options: nil).first(where: { 
            $0.node !== modelNode 
        })?.node
    
        return nnn
    }
    
    填充手势识别器@objc方法:

    @objc func moveModel(_ gesture: UIPanGestureRecognizer) {
    
        let location = gesture.location(in: self.sceneView)
    
        switch gesture.state {
            case .began:
                selectedNode = myMethod(at: location)
            case .changed:
                guard let result = self.sceneView.hitTest(location, 
                                                   types: .existingPlane).first 
                else { 
                    return 
                }
                let transform = result.worldTransform
                let newPosition = SIMD3<Float>(transform.columns.3.x, 
                                               transform.columns.3.y, 
                                               transform.columns.3.z)
                selectedNode?.simdPosition = newPosition
            default:
                selectedNode = nil
        }
    }
    
    @objc func moveModel(uu手势:uipangestureerecognizer){
    让位置=手势.位置(在:self.sceneView中)
    开关状态{
    案例.开始:
    selectedNode=myMethod(在:位置)
    案例。更改:
    防护等级结果=self.sceneView.hitTest(位置,
    类型:。现有平面)。首先
    否则{
    返回
    }
    let transform=result.worldTransform
    设newPosition=SIMD3(transform.columns.3.x,
    transform.columns.3.y,
    transform.columns.3.z)
    selectedNode?.simdPosition=newPosition
    违约:
    selectedNode=nil
    }
    }
    
    道歉。。。这意味着“dy”值始终为0.000000(而不是“dx”)标界,这有助于解决核心问题。我正在研究是否可以在不直接“触摸”节点的情况下使用平移手势移动节点,因为手指在平移操作期间隐藏了节点图像。希望,我可以移动节点,同时触摸其他地方。此外,还存在可靠性问题,因为在平移操作期间,节点偶尔会“跳出其所附着的表面”,并且似乎悬浮在其所附着的真实对象上方。将公布这些问题的任何进展。您认为将节点与ARAnchor关联将有助于解决第二个问题吗??,我尝试使用带有SCNNode的ARAnchor实现此功能,认为解决方案会更稳定。但我发现这没什么区别。如果我将摄影机从ARTargetHitPoint指向环境的其他部分,然后返回到虚拟对象过去所在的位置,则该对象有时会变得“未附着”,并重新附着在ARTargetHitPoint和物理摄影机之间的某个空间中。因此,我将不再追求这一点,因为它增加了不必要的复杂性。不稳定的锚栓系模型是由于跟踪不良(特征点数量不足,光线条件恶劣,容纳检测到的飞机的空间小,没有稳健的6自由度跟踪等),这就是为什么你有“浮动”模型…标定,是的,我理解这些问题。我不能依靠ARPlaneNode检测,因为我测量的平面一侧不大于25厘米。当我打开debugOptions来显示FeaturePoints时,它非常有用。当检测到一个或多个特征点时,是否可以使用代理或其他工具?我不想在应用程序发布供一般使用时启用debugOption。根据您的经验,实施ARAnchor是否会导致更可靠的特征跟踪(与使用不带ARAnchor的SCNnodes相比)?是的,ARAnchor与放置不带ARAnchor的几何体相比会导致更可靠的跟踪。但是特征点有自己的生活,它们不依赖于锚。
    @objc func moveModel(_ gesture: UIPanGestureRecognizer) {
    
        let location = gesture.location(in: self.sceneView)
    
        switch gesture.state {
            case .began:
                selectedNode = myMethod(at: location)
            case .changed:
                guard let result = self.sceneView.hitTest(location, 
                                                   types: .existingPlane).first 
                else { 
                    return 
                }
                let transform = result.worldTransform
                let newPosition = SIMD3<Float>(transform.columns.3.x, 
                                               transform.columns.3.y, 
                                               transform.columns.3.z)
                selectedNode?.simdPosition = newPosition
            default:
                selectedNode = nil
        }
    }