web-dev-qa-db-ja.com

ARKit –シーン内のARCameraの現在の位置を取得します

私はARKitとScenekitの両方を同時に学習している最中であり、それはちょっとした挑戦でした。

ARWorldTrackingSessionConfigurationセッションが作成されたので、シーンセッションでユーザーの「カメラ」の位置を取得する方法を誰かが知っているかどうか疑問に思いました。アイデアは、ユーザーの現在の位置に向かってオブジェクトをアニメーション化することです。

let reaperScene = SCNScene(named: "reaper.dae")!
let reaperNode = reaperScene.rootNode.childNode(withName: "reaper", recursively: true)!
reaperNode.position = SCNVector3Make(0, 0, -1)
let scene = SCNScene()
scene.rootNode.addChildNode(reaperNode)

// some unknown amount of time later   
let currentCameraPosition = sceneView.pointOfView?.position
let moveAction = SCNAction.move(to: currentCameraPosition!, duration: 1.0)
reaperNode.runAction(moveAction)

ただし、カメラを動かしても、currentCameraPositionは常に[0,0,0]のようです。私が間違っていることを知っていますか?最終的には、目に見えない球の周りでオブジェクトをカメラの前に回転させてアニメーション化し、次のようなことを行います: 仮想球の周りのオブジェクトを見てSCNCameraノードを回転 =(ユーザーがオブジェクトに向かってアニメーションを見る方法)

助けてくれてありがとう。

28
Ryan Pfister

自分を_ARSession.delegate_に設定します。セッションで処理されるすべてのフレームに対してARFrameを提供するsession(_:didUpdate:)を実装できます。フレームには、カメラの変換、回転、位置に関する情報を保持するcameraプロパティがあります。

_func session(_ session: ARSession, didUpdate frame: ARFrame) {
    // Do something with the new transform
    let currentTransform = frame.camera.transform
    doSomething(with: currentTransform)
}
_

rickster が指摘したように、_session.currentFrame_を呼び出すことで、常に現在のARFrameとカメラの位置を取得できます。これは、位置が一度だけ必要な場合、たとえばカメラがあったノードを移動する場合に便利ですが、カメラの位置の更新を取得する場合はdelegateメソッドを使用する必要があります。

23
jlsiewert

私はそれが解決されたことを知っていますが、私はそれのために少しきちんとした解決策を持っています..レンダラーデリゲートメソッドを追加することを好むでしょう..それはARSCNViewDelegateのメソッドです

func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
    guard let pointOfView = sceneView.pointOfView else { return }
    let transform = pointOfView.transform
    let orientation = SCNVector3(-transform.m31, -transform.m32, transform.m33)
    let location = SCNVector3(transform.m41, transform.m42, transform.m43)
    let currentPositionOfCamera = orientation + location
    print(currentPositionOfCamera)
}

もちろん、デフォルトで2つのSCNVector3を追加することはできません。したがって、クラスから次のように貼り付ける必要があります。

func +(lhv:SCNVector3, rhv:SCNVector3) -> SCNVector3 {
     return SCNVector3(lhv.x + rhv.x, lhv.y + rhv.y, lhv.z + rhv.z)
}
13

便宜上、インスタンスメソッドsession(_:didUpdate:)ViewController拡張を作成できます。コードは次のとおりです。

extension ViewController: ARSessionDelegate {

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        let transform = currentFrame.camera.transform 
        print("Updates")                               // UPDATING        
    }
}

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self                     // ARVIEW DELEGATE
    }   
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let configuration = ARWorldTrackingConfiguration()
        sceneView.session.run(configuration)
        sceneView.session.delegate = self             // ARSESSION DELEGATE
    }
}
2
ARGeo