私は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ノードを回転 =(ユーザーがオブジェクトに向かってアニメーションを見る方法)
助けてくれてありがとう。
自分を_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
メソッドを使用する必要があります。
私はそれが解決されたことを知っていますが、私はそれのために少しきちんとした解決策を持っています..レンダラーデリゲートメソッドを追加することを好むでしょう..それは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)
}
便宜上、インスタンスメソッド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
}
}