Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ARKit + SceneKitでMinesweeperを作ってみた

matuyuji
December 04, 2017

ARKit + SceneKitでMinesweeperを作ってみた

ARKit + SceneKitでマインスイーパーをつくってみました

matuyuji

December 04, 2017
Tweet

More Decks by matuyuji

Other Decks in Technology

Transcript

  1. Motivation • ARKitΛ࢖ͬͯԿ͔࡞ͬͯΈ͍ͨ • ͦͦ͜͜؆୯ͳήʔϜ͕Αͦ͞͏ • ฏ໘͕औΕͦ͏ & ࣗ෼ͷ৔ॴ͕Θ͔Γͦ͏ →

    ஍໘͕࢖͑ΔͳΒMinesweeperͱ͔Αͦ͞͏ → ARKit + SceneKitͰMinesweeperΛ࡞ͬͯΈΔ
  2. –ARKIT | Apple Developer Documentation “Augmented reality (AR) describes user

    experiences that add 2D or 3D elements to the live view from a device's camera in a way that makes those elements appear to inhabit the real world. ”
  3. ARKit • ϫʔϧυτϥοΩϯά • ฏ໘ݕग़ɺিಥ൑ఆɺޫݯ༧ଌ • ߴ౓ͳAPI (ࡉ͔͍ઃఆ͕ෆཁ) • ϞόΠϧͰಈ࡞

    • SceneKit, SpriteKit, Metal ARKit combines device motion tracking, camera scene capture, advanced scene processing, and display conveniences to simplify the task of building an AR experience.
  4. class ViewController: UIViewController, ARSCNViewDelegate { @IBOutlet var sceneView: ARSCNView! override

    func viewDidLoad() { super.viewDidLoad() sceneView.delegate = self sceneView.showsStatistics = true let scene = SCNScene(named: "art.scnassets/ship.scn")! sceneView.scene = scene } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let configuration = ARWorldTrackingConfiguration() sceneView.session.run(configuration) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } }
  5. ARSCNView ARSession ARCamera ARFrame ARConfiguration SCNScene run(_:options:) session scene currentFrame

    camera ARAnchor anchors • ܧঝؔ܎: UIView ← SCNView ← ARSCNView • σόΠεΧϝϥʹө͍ͬͯΔ಺༰Λγʔϯͷഎܠ ͱͯ͠දࣔ • ϢʔβͷҐஔ΍޲͖ͷมߋͰΧϝϥҐஔ͕มΘͬ ͨͱ͖ʹදࣔΛࣗಈͰมߋͯ͘͠ΕΔ
  6. ARSCNView ARSession ARCamera ARFrame ARConfiguration SCNScene run(_:options:) session scene currentFrame

    camera ARAnchor anchors • σόΠεΧϝϥͱϞʔγϣϯ ॲཧΛߦ͏ • ཪͰ͸AVCaptureSessionͱ CMMotionManagerΛ࢖͏ • ηογϣϯͷઃఆΛ͢Δந৅Ϋϥε • ฏ໘ݕग़ͱϙδγϣϯτϥοΩϯάΛ͍ͨ͠ ͳΒ͹ARWorldTrackingConfigurationΛ࢖͏ ֤ϑϨʔϜ͝ͱͷσόΠε Χϝϥͷը૾ͱϙδγϣϯ τϥοΩϯά৘ใΛ࣋ͭ Χϝϥ ϙδγϣϯτϥοΩ ϯά͞Ε͍ͯΔ΋ͷ
  7. class ViewController: UIViewController, ARSCNViewDelegate { @IBOutlet var sceneView: ARSCNView! override

    func viewDidLoad() { super.viewDidLoad() sceneView.delegate = self sceneView.showsStatistics = true let scene = SCNScene(named: "art.scnassets/ship.scn")! sceneView.scene = scene } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let configuration = ARWorldTrackingConfiguration() sceneView.session.run(configuration) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } }
  8. Plain Detection • ݕग़͞ΕΔͱARSCNViewDelegateͷ renderer(_:didAdd:for:)ͳͲ͕ݺ͹ΕΔ override func viewWillAppear(_ animated: Bool)

    { super.viewWillAppear(animated) let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = .horizontal sceneView.session.run(configuration) }
  9. renderer(_:didAdd:for:) The view calls this method once for each new

    anchor. ARKit also calls this method to provide visual content for any ARAnchor objects you manually add using the session's add(anchor:) method. optional func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) SCNSceneRendererDelegate func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { guard let planeAnchor = anchor as? ARPlaneAnchor else { return } → Planeݕग़࣌Ҏ֎ʹ΋ࣗ෼͕௥Ճͨ͠ͱ͖΋ݺ͹ΕΔ
  10. renderer(_:updateAtTime:) SceneKit calls this method exactly once per frame, so

    long as the SCNView object (or other SCNSceneRenderer object) displaying the scene is not paused. → γʔϯ͕ఀࢭ͠ͳ͍ݶΓɺຖϑϨʔϜݺ͹ΕΔ optional func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) SCNSceneRendererDelegate let planes = currentFrame.anchors.filter { $0 is ARPlaneAnchor }
  11. Hit Test for Plane • σόΠεεΫϦʔϯΛλοϓͨ͠ͱ͖ͳͲʹͲͷฏ໘ʹ৮ Ε͔ͨΛಘΒΕΔ • Χϝϥ͔Β͍ۙ΋ͷॱʹιʔτ͞Εͨ݁ՌΛฦ͢ @IBAction

    func handleTapGesture(_ tap: UITapGestureRecognizer) { let point = tap.location(in: sceneView) let results = sceneView.hitTest(point, types: .estimatedHorizontalPlane) ɿ }
  12. ΦϒδΣΫτͷ௥Ճ • SCNNodeΛARSCNViewͷscene΁௥Ճ͢Δ • δΦϝτϦͷ୯Ґ͸ϝʔτϧ • ΦϒδΣΫτͷҐஔ͕ۭؒ಺ʹݻఆ͞ΕΔ let geom =

    SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0) geom.firstMaterial!.diffuse.contents = UIColor.red geom.firstMaterial!.specular.contents = UIColor.white let node = SCNNode(geometry: geom) sceneView.scene.rootNode.addChildNode(node)
  13. Camera Position —ARKitExample func positionFromTransform(_ transform: matrix_float4x4) -> SCNVector3 {

    return SCNVector3Make(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z) } // Usage let position = positionFromTransform(camera.transform) let angles = camera.eulerAngles
  14. Position for Minesweeper • ΧϝϥͷҐஔ (= iPhoneΛ͍࣋ͬͯΔҐஔ) ͔Β஍໘ʹ ਨ௚ʹ߱Ζͨ͠఺ Λ

    ݱࡏͷҐஔ ͱ͢Δ • ࣮ࡍʹ͸30~40cm΄Ͳલʹདྷͯ͠·͏
 (ࠓճ͸ͦͷิਖ਼Λ͠ͳ͍)
  15. Plane Detection (࠶ܝ) • ஍໘΋ݕग़Ͱ͖Δ • ͔͠͠ɺݕग़ʹ͕͔͔࣌ؒΔ • ෦԰ͷܗঢ়ʹਖ਼͘͠Ԋͬͯݕग़͞Εͳ͍ •

    ్தͰฏ໘ͷϚʔδ͕ൃੜͨ͠Γ͢Δ • ྑ͍λΠϛϯάͰฏ໘ݕग़ΛࢭΊͨ΄͏͕Αͦ͞͏
  16. Game field for Minesweeper • Ұ൪େ͖͍ฏ໘Λ࢖͏ • Ұ൪௿͍Ґஔʹ͋Δฏ໘Λ࢖͏ • ࣗಈݕग़ΛఘΊͨ

    • δΣενϟ (ύϯɺϐϯνɺϩʔςʔτ) Ͱࣗ෼ͰϑΟʔϧυ ͷҐஔɺେ͖͞ɺճసΛௐ੔͢ΔΑ͏ʹͨ͠ • ࢦఆͨ͠αΠζͷηϧͰϑΟʔϧυΛຒΊΔΑ͏ʹͨ͠ ͦ΋ͦ΋্ख͘ݕग़Ͱ ͖͍ͯͳ͍ͷͰ্ख͘ ͍͔ͳ͍