第2章 ARKit 堤 修一/@shu223
■対応するアンカーの現在の状態に合うようにノードが(これから)更新される
func renderer(_ renderer: SCNSceneRenderer, willUpdate node: SCNNode, for anchor: ARAnchor)
■対応するアンカーの現在の状態に合うようにノードが更新された
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor)
■削除されたアンカーに対応するノードがシーンから削除された
func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor)
これらのデリゲートメソッドには、アンカーに対応するSCNNodeオブジェクトが渡されるので、次項で解説する検出した平面の可視化や、あとで解説する仮想オブジェクトの設置など、平面検出イベントに合わせてSceneKitで何らかの描画を行いたい場面で役立ちます。
2.3.4 検出した平面を可視化する
平面検出時にARSCNViewDelegateのrenderer(_:didAdd:for:)の引数に渡されるSCNNodeオブジェクトには、ジオメトリが割り当てられていません。つまり、そのままでは検出した平面は可視化されません。
しかし、検出した平面を可視化することは開発中は非常に重宝しますし、ARKitによって実現したい機能によっては任意のテクスチャで表示することもありえます。
検出した平面アンカーに対応するSCNNodeオブジェクトは、次のような手段で可視化できます。
■ジオメトリを割り当てる
■ジオメトリを持つ子ノードを追加する
平面ジオメトリを持つ子ノードを追加する実装例は次のとおりです。
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { guard let planeAnchor = anchor as? ARPlaneAnchor else {fatalError()} // 平面ジオメトリを作成……(1) let geometry = SCNPlane(width: CGFloat(planeAnchor.extent.x), height: CGFloat(planeAnchor.extent.z)) geometry.materials.first?.diffuse.contents = UIColor.yellow // 平面ジオメトリを持つノードを作成 let planeNode = SCNNode(geometry: geometry) // 平面ジオメトリを持つノードをx軸まわりに90度回転……(2) planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2.0, 1, 0, 0) DispatchQueue.main.async(execute: { // 検出したアンカーに対応するノードに子ノードとして持たせる node.addChildNode(planeNode) }) }
図2.4 検出した平面を可視化する