
落書きを3Dオブジェクトで表示するiPhoneアプリのサンプルコード
import UIKit
import SceneKit
private var myContext = 0
class ViewController: UIViewController {
weak var sceneView : SCNView?
weak var canvas : FreeHandView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.lightGrayColor()
setupScene()
createGround()
createCamera()
// freehand view
createCanvas()
}
func createGround() {
let ground = SCNBox(width: 20, height: 0.2, length: 20, chamferRadius: 0.1)
ground.firstMaterial?.diffuse.contents = UIColor.brownColor()
let groundNode = SCNNode(geometry: ground)
groundNode.physicsBody = SCNPhysicsBody.staticBody()
sceneView?.scene?.rootNode.addChildNode(groundNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 10, z: 20)
camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –0.2)
sceneView?.scene?.rootNode.addChildNode(camera)
}
func setupScene() {
let sv = SCNView(frame: CGRect(x: 0, y: 0, width: CGRectGetMaxX(view.bounds), height: 300))
sv.backgroundColor = UIColor.blackColor()
sv.scene = SCNScene()
sv.allowsCameraControl = true
sv.autoenablesDefaultLighting = true
view.addSubview(sv)
sceneView = sv
}
func createCanvas() {
let v = FreeHandView(frame: CGRectMake(5, 320, CGRectGetMaxX(view.bounds)-10, 300))
view.addSubview(v)
v.addObserver(self, forKeyPath: “objectPath”, options: .New, context: &myContext)
canvas = v
}
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if context == &myContext {
if let path = object.objectPath as UIBezierPath? {
var transform = CGAffineTransformIdentity
transform = CGAffineTransformScale(transform, 0.03, 0.03)
transform = CGAffineTransformTranslate(transform, -(path.bounds.origin.x + path.bounds.size.width * 0.5), -(path.bounds.origin.y + path.bounds.size.height * 0.5))
var pathTransformed = UIBezierPath(CGPath: CGPathCreateCopyByTransformingPath(path.CGPath, &transform))
pathTransformed.usesEvenOddFillRule = true
let shape = SCNShape(path: pathTransformed, extrusionDepth: 1.0)
shape.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let shapeNode = SCNNode(geometry: shape)
shapeNode.position = SCNVector3(x: 0, y: 12, z: 0)
shapeNode.physicsBody = SCNPhysicsBody.dynamicBody()
self.sceneView?.scene?.rootNode.addChildNode(shapeNode)
self.sceneView?.playing = true
}
}
}
deinit {
canvas?.removeObserver(self, forKeyPath: “objectPath”, context: &myContext)
}
}
class FreeHandView : UIView {
private var path : UIBezierPath = UIBezierPath()
dynamic var objectPath : UIBezierPath?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
layer.borderWidth = 1
layer.borderColor = UIColor.grayColor().CGColor
layer.cornerRadius = 20.0
layer.masksToBounds = true
multipleTouchEnabled = false
backgroundColor = UIColor.whiteColor()
path.lineWidth = 4.0
}
override func drawRect(rect: CGRect) {
UIColor.purpleColor().setStroke()
path.stroke()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
let p = touch.locationInView(self)
path.moveToPoint(p)
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
let p = touch.locationInView(self)
path.addLineToPoint(p)
setNeedsDisplay()
}
}
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
touchesMoved(touches, withEvent: event)
path.closePath()
objectPath = UIBezierPath(CGPath: path.CGPath)
path.removeAllPoints()
}
override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
touchesEnded(touches, withEvent: event)
}
}