ARKIT:如何像GiPHY World app一样在半空中移动物体

时间:2018-05-04 03:19:47

标签: ios swift scenekit arkit

我已经实现了一些方法,通过使用UIPanGesture移动表面顶部的对象,并利用平面光线投影技术..在拖动时定位对象的新坐标。

但是如果物体处于半空中,你就不能在任何飞机上进行光线投射。我注意到GIPHY World应用程序允许您在两种模式之间切换:

  1. 平面检测(允许物体仅放置在物体上) 表面)
  2. 自由模式(对象只能悬浮在相机前面)
  3. 当您将对象浮动时,用户可以在任何方向上拖动屏幕,即使您实际移动,对象也会正确跟随。我注意到你不必触摸物体来移动它,只要你在屏幕上拖动即可。

    我想知道你们是否可以提出一些代码来将2D屏幕拖动转换为3d对象的移动方式。实施例

    • 如果您在对象前面,请在屏幕上向上/向下拖动 将在Z坐标中移动对象...近或远。
    • 但如果你身体移动到一边......再次向上/向下拖动屏幕,对象现在会在X坐标上进行翻译。 < ---怎么样 他们这样做了吗?

    这是一个如何运作的视频。 https://youtu.be/16iMMuwjfIc

    在这里,您可以看到我在@ Vollan的答案中所尝试的内容。你可以看到重新定位如何像GiPHY APP一样工作。 https://youtu.be/ZoWj6WRBY58

1 个答案:

答案 0 :(得分:0)

所以,首先,我会在你移动后移动物体。

当您将节点放置在现实中时,您可以选择从摄像机角度制作节点,或者如果您确实想要将节点置于世界位置。

1:世界位置将Z,X,Y轴的原点放在启动AR会话时摄像机所在的位置。 2:摄像机位置意味着原点将跟随您并被绑定到摄像机。这将导致节点始终为3D。

现在,如果您选择世界位置,并选择绕节点或启动位置走动,例如90度。然后你将在轴的原点上有另一个角度,因为Z和X轴将改变位置。导致Z中的UP / DOWN转换为X.

其次我使用这段代码:

@objc func adjustWindow(_ gesture: UIPinchGestureRecognizer) {
    var startPosition: CGPoint = CGPoint(x: 0, y: 0)

    // Fetch location for touch in sceneView
    let location: CGPoint = gesture.location(in: sceneView)

    // Fetch targets at the current location
    let hits = self.sceneView.hitTest(location, options: nil)

    // Check if it's a node and it's a window node that has been touched
    guard let node = hits.first?.node, node.name == "name" else {return}

    // Make sure user is using 1 finger to move the view
    if gesture.numberOfTouches == 1 {
        switch gesture.state {
        case .failed, .cancelled, .ended:
            // Reset position after finished
            startPosition = CGPoint(x: 0, y: 0)
            break
        case .began:
            // Save start position, so that we can check how far the user have moved
            startPosition = location
        case .changed:
            // Fetch new x and y position
            let deltaX = Float(location.x - startPosition.x)/20
            let deltaY = Float(location.y - startPosition.y)/20

            // Transform and apply the new location
            let box = node.transform
            let translation = SCNMatrix4MakeTranslation(deltaX, deltaY, 1)
            let newTrans = SCNMatrix4Mult(box, translation)
            node.transform = newTrans

            node.localTranslate(by: SCNVector3Make(deltaX, deltaY, 1))
            // Set new location
            startPosition = location
        default:
            break
        }
        // Make sure user is using 2 fingers for scaling the view
    }
 }

这是我写这个场景的第一个版本,它的移动方式可能只适用于我的应用程序,因为我在.DAE文件中旋转/倾斜我的对象有点不对。但是你可能会想到获取触摸位置并跟踪它的变化。

实施  ARSessionDelegate

 var matrix: matrix_float4x4!

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        // Fetch and store current camera position
        matrix = frame.camera.transform
    }

当您移动相机时,它会随时更新您当前的相机位置。我还没弄明白如何应用这个。也许通过使用:

let translation = SCNMatrix4MakeTranslation(deltaX*matrix.m41, deltaY*matrix.m42, 1*matrix.m43)

或其他什么。

祝你好运。