iPhoneこの冬の鈴

この冬のあれが鈴だと聞いたので、鈴を表示するiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        self.setupScene()

        self.createBell()

        self.createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: self.view.bounds)

        sv.backgroundColor = UIColor(hue: 0, saturation: 0.7, brightness: 0.5, alpha: 1)

        sv.scene = SCNScene()

        sv.autoenablesDefaultLighting = true

        self.view.addSubview(sv)

        self.sceneView = sv

        

        //body

        let w : CGFloat = 40.0

        let h : CGFloat = 60.0

        

        for i in 0..<4 {

            switch i {

            case 01:

                let bar = SCNBox(width: w, height: 2, length: 2, chamferRadius: 1)

                let barNode = SCNNode(geometry: bar)

                barNode.position = SCNVector3(x:0, y: 0, z: (Float(i)-0.5) * Float(h))

                barNode.physicsBody = SCNPhysicsBody.staticBody()

                self.sceneView?.scene?.rootNode.addChildNode(barNode)

                

            default: //case 2…3:

                let bar = SCNBox(width: 2, height: 2, length: h, chamferRadius: 1)

                let barNode = SCNNode(geometry: bar)

                barNode.position = SCNVector3(x: (Float(i-2)-0.5) * Float(w), y: 0, z: 0)

                barNode.physicsBody = SCNPhysicsBody.staticBody()

                self.sceneView?.scene?.rootNode.addChildNode(barNode)

            }

        }

    }

    

    func createBell() {

        let node = SCNNode()

        self.sceneView?.scene?.rootNode.addChildNode(node)

        

        let bell = SCNSphere(radius: 10)

        bell.segmentCount = 48 * 3

        bell.firstMaterial?.diffuse.contents = UIColor(white: 0.9, alpha: 1)

        let bellNode = SCNNode(geometry: bell)

        bellNode.name = “bell”

        

        bellNode.transform = SCNMatrix4MakeScale(1.0, 0.11, 0.8)

        node.addChildNode(bellNode)

        

        for i in 0..<2 {

            let hole = SCNCylinder(radius: 1.3, height: 0.3)

            hole.firstMaterial?.diffuse.contents = UIColor(white: 0.1, alpha: 1)

            let holeNode = SCNNode(geometry: hole)

            holeNode.position = SCNVector3(x: –5 + Float(i) * 10, y: 1, z: 0)

            node.addChildNode(holeNode)

        }

        

        let line = SCNBox(width: 10, height: 0.2, length: 0.4, chamferRadius: 0)

        line.firstMaterial?.diffuse.contents = UIColor(white: 0.1, alpha: 1)

        let lineNode = SCNNode(geometry: line)

        lineNode.position = SCNVector3(x: 0, y: 1, z: 0)

        node.addChildNode(lineNode)

        

        node.physicsBody = SCNPhysicsBody.dynamicBody()

        node.physicsBody?.velocityFactor = SCNVector3(x: 1, y: 0, z: 1)

        node.physicsBody?.applyForce(SCNVector3(x: 10, y: 10, z: 0), impulse: true)

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let p = touches.anyObject()!.locationInView(self.sceneView)

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

            if hit.node.name == “bell” {

                let p0 = hit.node.parentNode!.presentationNode().position

                let p1 = hit.worldCoordinates

                let v = SCNVector3(x: 5.0*(p0.x – p1.x), y: 0, z: 5.0*(p0.z – p1.z))

                hit.node.parentNode?.physicsBody?.applyForce(v, atPosition: SCNVector3(x: p1.x, y: 0, z: p1.z), impulse: true)

            }

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.position = SCNVector3(x: 0, y: 70, z: 0)

        camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(-M_PI)/2.0)

        self.sceneView?.scene?.rootNode.addChildNode(camera)

    }

    

}