Skip to content

Instantly share code, notes, and snippets.

@mzsima
Created September 18, 2015 14:47
Show Gist options
  • Save mzsima/416519e7e36b24cdf9fd to your computer and use it in GitHub Desktop.
Save mzsima/416519e7e36b24cdf9fd to your computer and use it in GitHub Desktop.
Sprinkler
//
// ViewController.swift
// Sprinkler
//
// Created by MizushimaYusuke on 9/18/15.
// Copyright © 2015 MizushimaYusuke. All rights reserved.
//
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate, SCNPhysicsContactDelegate {
weak var sceneView : SCNView?
weak var sprinkler : SCNNode?
var play = false
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createGround()
createSprinkler()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.scene?.physicsWorld.contactDelegate = self
sv.backgroundColor = UIColor(hue: 0.55, saturation: 0.1, brightness: 0.9, alpha: 1)
sv.autoenablesDefaultLighting = true
sv.allowsCameraControl = true
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createGround() {
let ground = SCNBox(width: 10, height: 0.1, length: 10, chamferRadius: 0.1)
ground.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
let groundNode = SCNNode(geometry: ground)
groundNode.name = "ground"
groundNode.physicsBody = SCNPhysicsBody.staticBody()
groundNode.physicsBody?.categoryBitMask = 1 << 1
sceneView?.scene?.rootNode.addChildNode(groundNode)
}
func createSprinkler() {
let sk = SCNNode()
let body = SCNSphere(radius: 0.5)
body.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
let bodyNode = SCNNode(geometry: body)
bodyNode.position = SCNVector3(0, 0.5, 0)
sk.addChildNode(bodyNode)
let bar = SCNBox(width: 2, height: 0.2, length: 0.2, chamferRadius: 0.1)
bar.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
let barNode = SCNNode(geometry: bar)
barNode.position = SCNVector3(0, 0.8, 0)
sk.addChildNode(barNode)
sk.physicsBody = SCNPhysicsBody.dynamicBody()
sceneView?.scene?.rootNode.addChildNode(sk)
sprinkler = sk
}
var count = 0
var waterdrop : SCNSphere?
func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if !play { return }
sprinkler?.physicsBody?.angularVelocity = SCNVector4(0, 1, 0, 1)
sprinkler?.physicsBody?.velocity = SCNVector3(0, 0, 0)
if waterdrop == nil {
waterdrop = SCNSphere(radius: 0.1)
waterdrop?.firstMaterial?.diffuse.contents = UIColor(hue: 0.2, saturation: 0.2, brightness: 1, alpha: 1)
waterdrop?.firstMaterial?.specular.contents = UIColor.whiteColor()
}
if count == 0 {
let fx : Float = Float(arc4random() % 3) + 1
for i in 0...1 {
let wdropNode = SCNNode(geometry: waterdrop)
wdropNode.name = "water"
var r = -sprinkler!.presentationNode.rotation.w * sprinkler!.presentationNode.rotation.y
if i == 0 { r += Float(M_PI) }
let x = 1 * cos(r)
let z = 1 * sin(r)
let p = SCNVector3(x, 1.2, z)
wdropNode.position = p
wdropNode.physicsBody = SCNPhysicsBody.dynamicBody()
wdropNode.physicsBody?.applyForce(SCNVector3(p.x * fx, 3, p.z), impulse: true)
wdropNode.physicsBody?.contactTestBitMask = 1 << 1
sceneView?.scene?.rootNode.addChildNode(wdropNode)
}
}
count = (count + 1) % 10;
}
func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {
var water : SCNNode?
if contact.nodeA.name == "ground" && contact.nodeB.name == "water" {
water = contact.nodeB
}
else if contact.nodeB.name == "ground" && contact.nodeA.name == "water" {
water = contact.nodeA
}
if let water = water {
water.physicsBody?.type = .Static
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
play = true
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
play = false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment