ARKit을 다룰 때의 자세와 Tips

12082 단어 Xcode애플SwiftARKit

ARKit을 다룰 때의 자세와 Tips



ARKit에서 앱 개발을 할 때 의식하는 것이 좋은 것을 중심으로 정리해 보았습니다.

업데이트



2019/01/10 업데이트
여기도 참고하십시오
네이티브로 iOS AR 앱을 만드는 TIPS

AR과 SceneKit · SpriteKit의 관계



AR로 객체를 다룰 때,
· 3D의 경우 → ARSCNView (AR + SceneKit)
· 2D의 경우 → ARSKView (AR + SpriteKit)
같은 이미지가됩니다.

카메라 기능과 마찬가지로 session에 의해 관리되고 있어 session이 끊어지거나 하면 평면을 새롭게 인식하거나 현실 세계의 좌표를 인식할 수 없게 됩니다.

3D를 취급하는 경우, ARKit 자체 거기까지 어려운 일은 하지 않고, 인식한 좌표를 바탕으로 SceneKit로 노드를 추가하거나 하는 이미지가 됩니다.

SCNVector3 이해



ARKit을 다룰 때 현실 세계에 위치를 지정하여 배치하는 경우가 많지만,
SCNVecor3라는 것을 주로 사용합니다.
SceneKit을 다룬 적이있는 분은 친숙한가 생각합니다만,
AR을 취급할 때에도 이 SCNVecor3를 이용해 갑니다.



SCNVector3끼리 비교


extension SCNVector3: Equatable {
    public static func ==(to: SCNVector3, from: SCNVector3) -> Bool {
        return (to.x == from.x) && (to.y == from.y) && (to.z == from.z)
    }
}

탭한 위치의 현실 세계 좌표를 감지합니다.



hitTest를 이용해 검출을 실시합니다

ARSceneView의 화면상에 표시되어 있는 위치(ex: 탭한 부분)가 실제로 현실 세계에서 어느 좌표에 해당하는지 판정을 합니다.

이 기사도 참고해보세요.
ARKit에서 탭한 좌표를 감지하는 방법

 /* hitTest
  *  
  * x: 現実世界の横の軸になる
  * y: 現実世界の縦(高さ)の軸になる
  * z: 現実世界の奥行きの軸になる
  */
  let vector3 = SCNVector3.(hitResult.worldTransform.columns.3.x,
                            hitResult.worldTransform.columns.3.y,
                            hitResult.worldTransform.columns.3.z)

extension ARSCNView {

    /// 現実世界の座標に変換
    ///
    /// - Parameter screenPosition: CGPoint
    /// - Returns: SCNVector3
    func realWorldVector(screenPosition: CGPoint) -> SCNVector3? {
        let results = self.hitTest(screenPosition, types: [.existingPlane])
        guard let result = results.first else {
            return nil
        }

        // SCNVector3
        return SCNVector3.positionFromTransform(result.worldTransform)
    }
}

results.first 로서, 이것은, 인식한 평면의 수만큼 결과가 돌아오게 됩니다.
예를 들어, 바닥과 책상 각각 2곳의 평면을 인식한 경우는 인식한 순서대로 결과가 들어갑니다. 화면에서 책상 위치를 탭하면 책상 위의 탭한 좌표와 책상을 뚫은 끝에 있는 바닥의 평면 좌표의 2가지 결과를 얻을 수 있습니다.

객체 배치


let box = SCNBox(width: 0.25, height: 0.25, length: 0.25, chamferRadius: 0)
let node = SCNNode(geometry: box)
arscnView.scene.rootNode.addChildNode(node)

물체를 카메라 방향으로 향하도록



SCNText를 만들고 라벨을 카메라 방향으로 향하게 하려면
// 特定のNodeに対して向かせることも可能
let constraint = SCNLookAtConstraint(target: arscnView.pointOfView)     
constraint.isGimbalLockEnabled = true
textNode.constraints = [constraint]        

객체 삭제


textNode.removeFromParentNode()

현실 세계에서의 규모



방금 상자를 생성 한 크기를 살펴 보겠습니다.
let box = SCNBox(width: 0.25, height: 0.25, length: 0.25, chamferRadius: 0)
let node = SCNNode(geometry: box)
arscnView.scene.rootNode.addChildNode(node)

이 상자는 실제로 AR에서 확인하면,
종횡폭 25cm의 상자가 생성됩니다.

1 = 1m 환산이므로 주의하십시오.

평소의 앱 개발과 같이 view로 생성하고 있는 것과 같은 사이즈로 하면, 화면에 도저히 들어가지 않는 거대한 오브젝트가 생성되어 버립니다.

ARSCNViewDelegate



renderer



새롭게 앵커가 추가되었을 때



이것이 불릴 때,
앵커 추가됨 = 평면이 어딘가에서 인식 가능
라고 말할 수 있으므로, 유저에 대해 인식을 할 수 있었다고 전하는 타이밍 등에 이용하면 좋을 것입니다.
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

}

객체 업데이트



객체(또는 다른 객체)가 일시정지되어 있지 않는 한, 이 메소드를 프레임 마다 호출한다
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

}

장면을 렌더링 할 때 호출됩니다.


func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: 
    SCNScene, atTime time: TimeInterval) {

}

ARSession Observer



세션이 실패했을 때


func session(_ session: ARSession, didFailWithError error: Error) {
    // Present an error message to the user
    print(error)
}

세션이 중단되었을 때


func sessionWasInterrupted(_ session: ARSession) {
    // Inform the user that the session has been interrupted, for example, by presenting an overlay

}

세션 중단이 다시 시작되고 장치의 위치를 ​​다시 추적하면


func sessionInterruptionEnded(_ session: ARSession) {
    // Reset tracking and/or remove existing anchors if consistent tracking is required

}

좋은 웹페이지 즐겨찾기