
バレットタイムっぽく360度のカメラでスローなiPhoneアプリのサンプルコード
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createFigure()
createBlocks()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.backgroundColor = UIColor.darkGrayColor()
sv.scene = SCNScene()
sv.scene?.physicsWorld.speed = 0
sv.autoenablesDefaultLighting = true
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createFigure() {
let figure = SCNNode()
figure.name = “figure”
sceneView?.scene?.rootNode.addChildNode(figure)
let head = SCNCapsule(capRadius: 1, height: 8)
head.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let headNode = SCNNode(geometry: head)
headNode.transform = SCNMatrix4Scale(headNode.transform, 1, 0.25, 1)
headNode.position = SCNVector3(x: 0, y: 2, z: 0)
figure.addChildNode(headNode)
let body = SCNBox(width: 2.5, height: 2.5, length: 1.8, chamferRadius: 0.5)
body.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let bodyNode = SCNNode(geometry: body)
figure.addChildNode(bodyNode)
for var i=0; i<2; i++ {
let arm = SCNBox(width: 1, height: 2.3, length: 1, chamferRadius: 0.2)
arm.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let armNode = SCNNode(geometry: arm)
armNode.pivot = SCNMatrix4MakeTranslation(0, 0.6, 0)
armNode.transform = SCNMatrix4Rotate(armNode.transform, –Float(M_PI) * 0.7, 1, 0, 0)
armNode.transform = SCNMatrix4Translate(armNode.transform, i==0 ? 1.6 : –1.6, 0.6, 0)
figure.addChildNode(armNode)
}
for var i=0; i<2; i++ {
let foot = SCNBox(width: 1.2, height: 2.2, length: 1.4, chamferRadius: 0.2)
foot.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let footNode = SCNNode(geometry: foot)
footNode.pivot = SCNMatrix4MakeTranslation(0, 0.5, 0)
if i==0 {
footNode.transform = SCNMatrix4Rotate(footNode.transform, –Float(M_PI) * 0.4, 1, 0, 0)
}
footNode.transform = SCNMatrix4Translate(footNode.transform, i==0 ? 0.6 : –0.6, –2, 0)
figure.addChildNode(footNode)
}
figure.physicsBody = SCNPhysicsBody.dynamicBody()
}
func createBlocks() {
[Int](0…10).each { i in
let b = SCNBox(width: 1, height: 5, length: 1, chamferRadius: 0)
b.firstMaterial?.diffuse.contents = UIColor(hue: CGFloat(i) * 0.1, saturation: 0.4, brightness: 1, alpha: 1)
let bNode = SCNNode(geometry: b)
let w = Float(M_PI) / 3.0 * Float(i)
bNode.position = SCNVector3(x: 6.0 * cos(w), y: –Float(i) * 2.0, z: 6.0 * sin(w))
self.sceneView?.scene?.rootNode.addChildNode(bNode)
}
}
func createCamera() {
let camera = SCNNode()
camera.name = “camera”
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 40)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
sceneView?.scene?.physicsWorld.speed = 0.4
sceneView?.playing = true
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if let camera = sceneView?.scene?.rootNode.childNodeWithName(“camera”, recursively: false) {
camera.constraints = nil
camera.transform = SCNMatrix4Rotate(camera.transform, Float(M_PI) * 0.005, 0, 1, 0)
if let figure = self.sceneView?.scene?.rootNode.childNodeWithName(“figure”, recursively: false) {
let constraint = SCNLookAtConstraint(target: figure)
camera.constraints = [constraint]
}
}
}
}
extension Array {
func each(doit:T -> Void) {for i in self {doit(i)}}
}