2017-07-13 57 views
14

Jestem w trakcie uczenia się jednocześnie ARKit i Scenekit, i to było trochę wyzwaniem.ARKit - Zdobądź aktualną pozycję "kamery" na scenie

Po utworzeniu sesji ARWorldTrackingSessionConfiguration zastanawiałem się, czy ktokolwiek wiedział, jak uzyskać pozycję "aparatu" użytkownika w sesji sceny. Chodzi o to, że chcę animować obiekt w kierunku aktualnej pozycji użytkownika.

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) 

Jednak wydaje się, że currentCameraPosition jest zawsze [0,0,0], mimo że poruszam kamerą. Masz pojęcie, co robię źle? W końcu chciałbym obrócić obiekt wokół niewidzialnej kuli, aż znajdzie się przed kamerą, a następnie ją ożywić, robiąc coś podobnego do tego: Rotate SCNCamera node looking at an object around an imaginary sphere (w ten sposób użytkownik widzi, że obiekt ożywia się w jego kierunku)

Dzięki za pomoc.

Odpowiedz

14

Ustaw jako ARSession.delegate. Następnie możesz zaimplementować session(_:didUpade:), która da Ci ARFrame dla każdej ramki przetworzonej w twojej sesji. Ramka ma właściwość camera, która przechowuje informacje o transformacji, obrocie i położeniu kamery.

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

Edit: Jak @rickster wskazał, że zawsze można uzyskać aktualny ARFrame i położenie kamery poprzez nią, wywołując session.currentFrame. Jest to przydatne, gdy potrzebujesz pozycji tylko raz, np. Aby przesunąć węzeł w miejscu, w którym znajdowała się kamera, ale powinieneś użyć metody delegate, jeśli chcesz otrzymywać aktualizacje dotyczące położenia kamery.

+1

To działa, ale można również uzyskać ramek nie będąc delegatem sesja dostając 'currentFrame' sesji za własność. – rickster

+1

@Rickster jesteś napięty i edytowałem odpowiedź, ale zazwyczaj chcesz, aby inne węzły reagowały na ciebie zmieniając twoją pozycję, np. Podążając za tobą. W takim razie chcesz ciągłe aktualizacje nowych ujęć kamery. – orangenkopf

+1

Prawda. Punktem jest, w zależności od tego, jak twoja aplikacja jest inaczej skonfigurowana, możesz mieć ARKita dostarczającego ci klatki z szybkością 60 klatek na sekundę i renderowania, gdy je otrzymasz, lub możesz uruchomić własną pętlę renderowania przy (do) 60 fps i zapytać ARKit dla ramki za każdym razem, gdy jej potrzebujesz. Obsługuje oba sposoby, więc używaj tego, co chcesz. – rickster

6

wiem, że został rozwiązany ale mam mały zgrabny rozwiązanie dla niego .. chciałbym preferują dodanie metody renderowania delegata .. jest to metoda w 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) 
} 

oczywiście nie można domyślnie dodać dwa SCNVector3 wyjęciu z pudełka .. więc trzeba wkleić z klasy następujących

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

Dlaczego właśnie bierzesz przekątne wpisy macierzy obrotu? I dlaczego "pozycja" jest równa "orientacja + lokalizacja". Pozycja to lokalizacja, tj.ostatnia kolumna transformacji. Górna lewa macierz 3x3 zawiera orientację (i ewentualnie skalę i ścinanie). Istnieją różne metody wydobywania z niej tonu, odchylenia i przechyłu, ale przekątna nie jest jedną z nich. – kjyv