iPhoneモビール

球と板2枚のモビールを表示するiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController, SCNSceneRendererDelegate {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createMobile()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor.blackColor()

        sv.scene = SCNScene()

        sv.autoenablesDefaultLighting = true

        sv.delegate = self

        view.addSubview(sv)

        

        sceneView = sv

    }

    

    func createMobile() {

        let addBar = { (width:CGFloat, height:CGFloat, position:SCNVector3) -> SCNNode in

            let bar = SCNBox(width: width, height: height, length: 0.1, chamferRadius: 0)

            bar.firstMaterial?.diffuse.contents = UIColor.whiteColor()

            let barNode = SCNNode(geometry: bar);

            barNode.position = position

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

            

            barNode.physicsBody = SCNPhysicsBody.dynamicBody()

            return barNode

        }

        

        let nA = addBar(0.1, 2, SCNVector3(x: 0, y: 11, z: 0))

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(body: nA.physicsBody, anchor: SCNVector3(x: 0, y: 1, z: 0)))

        

        let nB = addBar(10, 0.1, SCNVector3(x: 0, y: 10, z: 0))

        nB.name = “main bar”

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nA.physicsBody, anchorA: SCNVector3Make(0, –0.9, 0), bodyB: nB.physicsBody, anchorB: SCNVector3Make(0, 0.2, 0)))

        

        

        // Left

        let nC = addBar(0.1, 5, SCNVector3(x: –5, y: 7.5, z: 0))

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nB.physicsBody, anchorA: SCNVector3Make(-5, –0.1, 0), bodyB: nC.physicsBody, anchorB: SCNVector3Make(0, 2.5, 0)))

        

        let nD = addBar(6, 0.1, SCNVector3(x: –5, y: 5, z: 0))

        nD.name = “left bar”

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nC.physicsBody, anchorA: SCNVector3Make(0, –2.6, 0), bodyB: nD.physicsBody, anchorB: SCNVector3Make(0, 0.2, 0)))

        

        let nE = addBar(0.1, 4, SCNVector3(x: –8, y: 3, z: 0))

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nD.physicsBody, anchorA: SCNVector3Make(-3, –0.1, 0), bodyB: nE.physicsBody, anchorB: SCNVector3Make(0, 2.1, 0)))

        

        let nF = addBar(0.1, 2, SCNVector3(x: –2, y: 4, z: 0))

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nD.physicsBody, anchorA: SCNVector3Make(3, –0.1, 0), bodyB: nF.physicsBody, anchorB: SCNVector3Make(0, 1.1, 0)))

        

        

        let boxL = SCNBox(width: 3, height: 3, length: 0.2, chamferRadius: 0)

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

        let boxNodeL = SCNNode(geometry: boxL)

        boxNodeL.position = SCNVector3(x: –8, y: –1, z: 0)

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

        boxNodeL.physicsBody = SCNPhysicsBody.dynamicBody()

        boxNodeL.physicsBody?.mass = 3.0

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nE.physicsBody, anchorA: SCNVector3Make(0, –2.1, 0), bodyB: boxNodeL.physicsBody, anchorB: SCNVector3Make(0, 1.6, 0)))

        

        

        let boxR = SCNBox(width: 2, height: 2, length: 0.2, chamferRadius: 0)

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

        let boxNodeR = SCNNode(geometry: boxR)

        boxNodeR.position = SCNVector3(x: –2, y: 2, z: 0)

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

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

        boxNodeR.physicsBody = SCNPhysicsBody.dynamicBody()

        boxNodeR.physicsBody?.mass = 3.0

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nF.physicsBody, anchorA: SCNVector3Make(0, –1.1, 0), bodyB: boxNodeR.physicsBody, anchorB: SCNVector3Make(1.3, 1.3, 0)))

        

        

        

        

        // Right

        let nG = addBar(0.1, 8, SCNVector3(x: 5, y: 6, z: 0))

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nB.physicsBody, anchorA: SCNVector3Make(5, –0.1, 0), bodyB: nG.physicsBody, anchorB: SCNVector3Make(0, 4.1, 0)))

        let ball = SCNSphere(radius: 2)

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

        let ballNode = SCNNode(geometry: ball)

        ballNode.position = SCNVector3(x: 5, y: –1, z: 0)

        ballNode.physicsBody = SCNPhysicsBody.dynamicBody()

        ballNode.physicsBody?.mass = 9

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

        sceneView?.scene?.physicsWorld.addBehavior(SCNPhysicsBallSocketJoint(bodyA: nG.physicsBody, anchorA: SCNVector3Make(0, –4.1, 0), bodyB: ballNode.physicsBody, anchorB: SCNVector3Make(0, 2.1, 0)))

        

    }

    

    

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

        let mainbar = sceneView?.scene?.rootNode.childNodeWithName(“main bar”, recursively: false)

        mainbar?.physicsBody?.angularVelocity = SCNVector4(x: 0, y: 1, z: 0, w: 0.4)

        

        let leftbar = sceneView?.scene?.rootNode.childNodeWithName(“left bar”, recursively: false)

        leftbar?.physicsBody?.angularVelocity = SCNVector4(x: 0, y: 1, z: 0, w: –1.0)

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

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

    }

}