ARKitでEyeTrackingを試してみた

はじめに

ARKitにはrightEyeTrnsfomr, leftEyeTransformという両目の角度とxyz座標を取得できるパラメータが用意されています。

今回は使用していませんがlookAtPointというみている方向も取得することができます。

今回は球のオブジェクトに目のテクスチャを貼り付けてEyeTrackinを試してみました

コード

正直あまり理解できていないんですがsimdPivotを目のnodeに追加しておかないと座標が変なところに吹っ飛んで表示されなくなってしまいます。

Tracking and Visualizing FacesのサンプルをいじっていてsimdPivotがいたので追加したら動きました。

import ARKit
import SceneKit
import UIKit

class ViewController: UIViewController, ARSessionDelegate {
    @IBOutlet var sceneView: ARSCNView! {
        didSet {
            sceneView.delegate = self
        }
    }
    
    var contentNode: SCNNode?
    
    var leftEyeNode: SCNNode = {
        let node = SCNNode()
        node.geometry = SCNSphere(radius: 0.1)
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "eyeTexture")
        node.geometry?.materials = [material]
        node.position = SCNVector3(0, 0, 0.1)
        return node
    }()
    
    var rightEyeNode: SCNNode = {
        let node = SCNNode()
        node.geometry = SCNSphere(radius: 0.1)
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "eyeTexture")
        node.geometry?.materials = [material]
        node.position = SCNVector3(0, 0, 0.1)
        return node
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let configuration = ARFaceTrackingConfiguration()
        sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
        
    }
}

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        guard anchor is ARFaceAnchor else { return nil }
        contentNode = SCNNode()
        
        rightEyeNode.simdPivot = float4x4(diagonal: [10, 10, 10, 1])
        leftEyeNode.simdPivot = float4x4(diagonal: [10, 10, 10, 1])
        
        guard let anchorNode = contentNode else { return nil }
        anchorNode.addChildNode(leftEyeNode)
        anchorNode.addChildNode(rightEyeNode)
        return contentNode
    }

    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        guard let faceAnchor = anchor as? ARFaceAnchor else { return }
        
        rightEyeNode.simdTransform = faceAnchor.rightEyeTransform
        leftEyeNode.simdTransform = faceAnchor.leftEyeTransform
    }
}

前の記事

List