
長い棒のまわりを短い棒が周るiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController, SCNPhysicsContactDelegate {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createPole()
createCamera()
createBar()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.scene?.physicsWorld.contactDelegate = self
sv.backgroundColor = UIColor(hue: 0.3, saturation: 0.2, brightness: 1, alpha: 1)
sv.allowsCameraControl = true
self.view.addSubview(sv)
self.sceneView = sv
}
func createPole() {
let cy = SCNCylinder(radius: 0.5, height: 20)
cy.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.7, brightness: 1, alpha: 1)
let cyNode = SCNNode(geometry: cy)
cyNode.physicsBody = SCNPhysicsBody.staticBody()
cyNode.physicsBody?.restitution = 0
self.sceneView?.scene?.rootNode.addChildNode(cyNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: –10, y: 0, z: 30)
self.sceneView?.scene?.rootNode.addChildNode(camera)
}
func createBar() {
let bar = SCNCylinder(radius: 0.3, height: 6)
bar.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 1, brightness: 0.7, alpha: 1)
let barNode = SCNNode(geometry: bar)
barNode.name = “bar”
barNode.position = SCNVector3(x: –30, y: 0, z: 0)
barNode.rotation = SCNVector4Make(1, 0, 0, Float(M_PI)/2.0)
self.sceneView?.scene?.rootNode.addChildNode(barNode)
barNode.runAction(SCNAction.repeatActionForever(SCNAction.sequence([SCNAction.moveTo(SCNVector3(x: –30, y: 10, z: 2), duration: 0.5), SCNAction.moveTo(SCNVector3(x: –30, y: –10, z: 2), duration: 0.5)])))
barNode.physicsBody?.restitution = 0
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let bar = self.sceneView?.scene?.rootNode.childNodeWithName(“bar”, recursively: false) {
bar.removeAllActions()
bar.physicsBody = SCNPhysicsBody.dynamicBody()
bar.physicsBody?.applyForce(SCNVector3(x: 40, y: 0, z: 0), atPosition: SCNVector3(x: 0, y: 0, z: 0), impulse: true)
}
}
func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {
let bar = [contact.nodeA, contact.nodeB].filter { ($0 as SCNNode).name == “bar” }.first
if bar == nil { return }
let ring = SCNTube(innerRadius: 1.5, outerRadius: 1.5, height: 0.1)
ring.firstMaterial?.diffuse.contents = UIColor.clearColor()
let ringNode = SCNNode(geometry: ring)
ringNode.position = bar!.presentationNode().convertPosition(contact.contactPoint, fromNode:self.sceneView?.scene?.rootNode)
ringNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI)/2.0)
bar?.addChildNode(ringNode)
let v = bar?.physicsBody?.velocity
let w = bar?.physicsBody?.angularVelocity
bar?.physicsBody = SCNPhysicsBody.dynamicBody()
bar?.physicsBody?.physicsShape = SCNPhysicsShape(node: bar!, options: [SCNPhysicsShapeTypeKey: SCNPhysicsShapeTypeConcavePolyhedron])
bar?.physicsBody?.velocity = v!
bar?.physicsBody?.angularVelocity = w!
bar?.name = “”
self.createBar()
}
}