
球と板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)
}
}