
ギアをくるくる回してチューブの中のドアを開けるiPhoneアプリのサンプルコード
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createTube()
createGear()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.backgroundColor = UIColor.lightGrayColor()
sv.scene = SCNScene()
sv.autoenablesDefaultLighting = true
sv.allowsCameraControl = true
view.addSubview(sv)
sceneView = sv
}
func createTube() {
let tube = SCNTube(innerRadius: 2, outerRadius: 2.1, height: 20)
tube.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.3, brightness: 1, alpha: 1).colorWithAlphaComponent(0.3)
let tubeNode = SCNNode(geometry: tube)
sceneView?.scene?.rootNode.addChildNode(tubeNode)
tubeNode.physicsBody = SCNPhysicsBody.staticBody()
tubeNode.physicsBody?.categoryBitMask = 0x1 << 1
tubeNode.physicsBody?.physicsShape = SCNPhysicsShape(node: tubeNode, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron])
let door = SCNCylinder(radius: 2, height: 0.2)
door.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.3, brightness: 1, alpha: 1)
let doorNode = SCNNode(geometry: door)
doorNode.name = “door”
sceneView?.scene?.rootNode.addChildNode(doorNode)
doorNode.physicsBody = SCNPhysicsBody.staticBody()
doorNode.physicsBody?.collisionBitMask = 0x1
}
func createGear() {
let gear = SCNNode()
gear.name = “gear”
sceneView?.scene?.rootNode.addChildNode(gear)
gear.transform = SCNMatrix4Rotate(gear.transform, Float(M_PI)/2.0, 1, 0, 0)
gear.transform = SCNMatrix4Translate(gear.transform, 0, 0, 2.5)
let base = SCNTube(innerRadius: 0.8, outerRadius: 1.4, height: 0.2)
base.firstMaterial?.diffuse.contents = UIColor.blueColor()
let baseNode = SCNNode(geometry: base)
gear.addChildNode(baseNode)
[Int](0…12).each {
let t = SCNBox(width: 0.4, height: 0.2, length: 0.4, chamferRadius: 0.05)
t.firstMaterial?.diffuse.contents = base.firstMaterial?.diffuse.contents
let tn = SCNNode(geometry: t)
let w = M_PI / 6.0 * Double($0)
let x = 1.5 * sin(w)
let z = 1.5 * cos(w)
tn.position = SCNVector3(x: Float(x), y: 0, z: Float(z))
tn.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(w))
gear.addChildNode(tn)
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let c = count % 3
switch c {
case 1:
let door = sceneView?.scene?.rootNode.childNodeWithName(“door”, recursively: false)
door?.runAction(SCNAction.moveTo(SCNVector3(x: 4, y: 0, z: 0), duration: 2.0))
let gear = sceneView?.scene?.rootNode.childNodeWithName(“gear”, recursively: false)
gear?.runAction(SCNAction.rotateByAngle(CGFloat(M_PI) * 2.0, aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 2.0))
case 2:
let door = sceneView?.scene?.rootNode.childNodeWithName(“door”, recursively: false)
door?.runAction(SCNAction.moveTo(SCNVector3Zero, duration: 2.0))
let gear = sceneView?.scene?.rootNode.childNodeWithName(“gear”, recursively: false)
gear?.runAction(SCNAction.rotateByAngle(-CGFloat(M_PI) * 2.0, aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 2.0))
default:
let ball = SCNSphere(radius: 1)
ball.firstMaterial?.diffuse.contents = UIColor.orangeColor()
let ballNode = SCNNode(geometry: ball)
ballNode.position = SCNVector3(x: 0, y: 10, z: 0)
ballNode.physicsBody = SCNPhysicsBody.dynamicBody()
self.sceneView?.scene?.rootNode.addChildNode(ballNode)
delay(10.0) { ballNode.removeFromParentNode() }
}
++count
}
final func delay(delay:Double, doit:() -> Void) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), doit)
}
}
extension Array {
func each(doit:T -> Void) {for i in self {doit(i);}}
}