iPhone輪と線

輪に線をペタペタ貼り付けて、くるくる回すiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController, SCNSceneRendererDelegate {

    weak var sceneView : SCNView?

    var marks = [SCNNode]()

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createRing()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor(hue: 0.45, saturation: 0.2, brightness: 1, alpha: 1)

        sv.scene = SCNScene()

        sv.delegate = self

        view.addSubview(sv)

        sceneView = sv

    }

    

    func createRing() {

        for var i=0; i<2; i++ {

            let ring = SCNTube(innerRadius: 6, outerRadius: 12, height: 1)

            ring.firstMaterial?.diffuse.contents = UIColor(hue: 0.25, saturation: 0.1, brightness: 1, alpha: 1)

            let ringNode = SCNNode(geometry: ring)

            ringNode.position = SCNVector3(x: 0, y: 2040 * Float(i), z: 0)

            ringNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI) * 0.5)

            sceneView?.scene?.rootNode.addChildNode(ringNode)

            

            ringNode.runAction(SCNAction.repeatActionForever(SCNAction.rotateByAngle(i==0 ? –CGFloat(M_PI) : CGFloat(M_PI), aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 1.0)))

        }

    }

    

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        if let p = (touches.first as? UITouch)?.locationInView(self.view) {

            if let hit = sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey : true])?.first as? SCNHitTestResult {

                let lp = hit.localCoordinates

                let mark = SCNSphere(radius: 1)

                mark.firstMaterial?.diffuse.contents = UIColor(hue: 0.8, saturation: 0.2, brightness: 1, alpha: 1)

                let markNode = SCNNode(geometry: mark)

                markNode.position = lp

                hit.node.addChildNode(markNode)

                

                marks.append(markNode)

            }

        }

    }

    

    func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {

        sceneView?.scene?.rootNode.childNodes

            .filter {($0 as! SCNNode).name == “line”}

            .map {

                ($0 as! SCNNode).removeFromParentNode()

            }

        

        for var i=0; i<marks.count1; i+=2 {

            let pts:[SCNVector3] = [marks[i], marks[i+1]].map { (mark : SCNNode) -> SCNVector3 in

                return mark.parentNode!.convertPosition(mark.position, toNode: self.sceneView?.scene?.rootNode) as SCNVector3

            }

            

            var verts : [SCNVector3] = pts;

            let indices : [Int32] = [0, 1];

            let vertexSource = SCNGeometrySource(vertices:UnsafePointer<SCNVector3>(verts), count:verts.count);

            let indexData = NSData(bytes:indices, length:sizeof(Int32) * indices.count);

            let element = SCNGeometryElement(data:indexData, primitiveType:.Line, primitiveCount:indices.count, bytesPerIndex:sizeof(Int32));

            let line = SCNGeometry(sources:[vertexSource], elements:[element]);

            line.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 1, brightness: 1, alpha: 1)

            let lineNode = SCNNode(geometry:line)

            lineNode.name = “line”

            sceneView?.scene?.rootNode.addChildNode(lineNode)

        }

    }

}