棒をくるくる回しておいて、タップしたらそこにスタンプなiPhoneアプリのサンプルコードを描いてみます。(結構な頻度で exec bad access…)
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
var push : Bool = false
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
self.createStampBoard()
self.createStampHand()
self.createCamera()
self.createLight()
}
func setupScene() {
let w = CGRectGetMaxX(self.view.bounds)
let sv = SCNView(frame: CGRect(x: 0, y: 0, width: w, height: w))
sv.backgroundColor = UIColor(hue: 0.2, saturation: 0.1, brightness: 1, alpha: 1)
sv.scene = SCNScene()
sv.scene?.physicsWorld.gravity = SCNVector3Zero
sv.delegate = self
self.view.addSubview(sv)
self.sceneView = sv
}
func createStampBoard()
{
let board = SCNBox(width: 40, height: 40, length: 1, chamferRadius: 0)
board.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.4, brightness: 1, alpha: 1)
let boardNode = SCNNode(geometry: board)
self.sceneView?.scene?.rootNode.addChildNode(boardNode)
}
func createStampHand() {
let hand = SCNCylinder(radius: 0.5, height: 20)
hand.firstMaterial?.diffuse.contents = UIColor(hue: 0.4, saturation: 0.9, brightness: 0.6, alpha: 1)
let handNode = SCNNode(geometry: hand)
handNode.name = “hand”
handNode.position = SCNVector3(x: 0, y: 10, z: 4.0)
self.sceneView?.scene?.rootNode.addChildNode(handNode)
self.addBodyToHand()
let stamp = SCNCylinder(radius: 2, height: 3)
stamp.firstMaterial?.diffuse.contents = UIColor(hue: 0.6, saturation: 0.5, brightness: 1, alpha: 1)
let stampNode = SCNNode(geometry: stamp)
stampNode.name = “stamp”
stampNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI/2.0))
stampNode.position = SCNVector3(x:0, y:7, z:0)
handNode.addChildNode(stampNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 40)
self.sceneView?.scene?.rootNode.addChildNode(camera)
}
func createLight() {
let light = SCNLight()
light.type = SCNLightTypeOmni
let lightNode = SCNNode()
lightNode.light = light
lightNode.position = SCNVector3(x: 0, y: –20, z: 50)
self.sceneView?.scene?.rootNode.addChildNode(lightNode)
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
// some time bad access …
if (push) {
return
}
if let hand = self.sceneView?.scene?.rootNode.childNodeWithName(“hand”, recursively: false) {
let v = SCNVector3(x: hand.presentationNode().position.y/3.0, y: -hand.presentationNode().position.x/3.0, z: 0)
if let body = hand.physicsBody {
body.applyForce(v, impulse: false)
}
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let hand = self.sceneView?.scene?.rootNode.childNodeWithName(“hand”, recursively: false)? {
if let body = hand.physicsBody?{
self.push = true
body.velocity = SCNVector3Zero
body.angularVelocity = SCNVector4Zero
self.sceneView?.scene?.physicsWorld.removeAllBehaviors()
let joint = SCNPhysicsHingeJoint(body: hand.physicsBody!, axis:SCNVector3(x: 1, y: 0, z: 0) , anchor: SCNVector3(x: 0, y: –9, z: 0))
self.sceneView?.scene?.physicsWorld.addBehavior(joint)
let op = hand.presentationNode().position
let ow = hand.presentationNode().rotation
body.applyForce(SCNVector3(x: 0, y: 0, z: –10), impulse:true);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(Double(NSEC_PER_SEC) * 0.2)), dispatch_get_main_queue(), {
self.stamp()
hand.physicsBody = nil
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(0.1)
hand.presentationNode().position = op
hand.presentationNode().rotation = ow
SCNTransaction.setCompletionBlock({ () -> Void in
self.addBodyToHand()
self.push = false
})
SCNTransaction.commit()
})
}
}
}
func stamp () {
if let hand = self.sceneView?.scene?.rootNode.childNodeWithName(“hand”, recursively: false) {
let s = SCNBox(width: 3, height: 3, length: 0.1, chamferRadius: 0)
s.firstMaterial?.diffuse.contents = UIColor(hue: 0, saturation: 0.3, brightness: 1, alpha: 1)
let sNode = SCNNode(geometry: s)
var stampPosition = hand.presentationNode().position
sNode.position = SCNVector3(x: 1.8 * stampPosition.x, y: 1.8 * stampPosition.y, z: 1)
self.sceneView?.scene?.rootNode.addChildNode(sNode)
}
}
func addBodyToHand () {
self.sceneView?.scene?.physicsWorld.removeAllBehaviors()
if let handNode = self.sceneView?.scene?.rootNode.childNodeWithName(“hand”, recursively: false) {
handNode.physicsBody = SCNPhysicsBody.dynamicBody()
handNode.physicsBody?.allowsResting = false
let joint = SCNPhysicsHingeJoint(body: handNode.physicsBody!, axis:SCNVector3(x: 0, y: 0, z: 1) , anchor: SCNVector3(x: 0, y: –9, z: 0))
self.sceneView?.scene?.physicsWorld.addBehavior(joint)
}
}
}