J'apprends à la fois ARKit et Scenekit simultanément, et le défi a été difficile.
Avec la création d'une session ARWorldTrackingSessionConfiguration, je me demandais si quelqu'un connaissait un moyen d'obtenir la position de la "caméra" de l'utilisateur dans la session de la scène. L'idée est que je veux animer un objet vers la position actuelle de l'utilisateur.
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)
Cependant, il semble que currentCameraPosition soit toujours [0,0,0], même si je déplace la caméra. Une idée de ce que je fais mal? Finalement, l’idée est de faire pivoter l’objet autour d’une sphère invisible jusqu’à ce qu’il se trouve devant la caméra, puis de l’animer, en effectuant une opération semblable à celle-ci: le nœud Rotation SCNCamera regarde un objet autour d’une sphère imaginaire = (de cette façon, l'utilisateur voit l'objet s'animer vers lui)
Merci pour toute aide.
Définissez-vous comme le ARSession.delegate
. Ensuite, vous pouvez implémenter session(_:didUpdate:)
qui vous donnera un ARFrame
pour chaque image traitée dans votre session. Le cadre a une propriété camera
qui contient des informations sur la transformation, la rotation et la position des caméras.
func session(_ session: ARSession, didUpdate frame: ARFrame) {
// Do something with the new transform
let currentTransform = frame.camera.transform
doSomething(with: currentTransform)
}
Comme rickster a souligné que vous pouvez toujours obtenir le ARFrame
actuel et la position de la caméra à travers lui en appelant session.currentFrame
. Ceci est utile si vous avez besoin de la position une seule fois, par exemple pour déplacer un noeud à l'emplacement de la caméra, mais vous devez utiliser la méthode delegate
si vous souhaitez obtenir des mises à jour de la position de la caméra.
Je sais qu'il a été résolu, mais j'ai une petite solution soignée pour cela .. Je préférerais ajouter une méthode de rendu du délégué .. c'est une méthode dans 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)
}
bien sûr, vous ne pouvez pas ajouter les deux SCNVector3 par défaut .. vous devez donc coller hors de la classe les éléments suivants
func +(lhv:SCNVector3, rhv:SCNVector3) -> SCNVector3 {
return SCNVector3(lhv.x + rhv.x, lhv.y + rhv.y, lhv.z + rhv.z)
}
Pour votre commodité, vous pouvez créer une extension ViewController
avec une méthode d'instance session(_:didUpdate:)
. Voici le code:
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
}
}