Skip to content

Instantly share code, notes, and snippets.

@jungchris
Last active July 10, 2020 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jungchris/ccb652b55022a26ce356f30e1ad9f37e to your computer and use it in GitHub Desktop.
Save jungchris/ccb652b55022a26ce356f30e1ad9f37e to your computer and use it in GitHub Desktop.
ARKit iOS Workshop 4 - Hit Testing and Basic Anmiations
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
sceneView.addGestureRecognizer(tapGestureRecognizer)
// Set the view's delegate
// sceneView.delegate = self
// Show statistics such as fps and timing information
// sceneView.showsStatistics = true
// Create a new scene
sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
// Set the scene to the view
sceneView.session.run(configuration)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Run the view's session
// sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
@IBAction func buttonPlay(_ sender: Any) {
addRobot()
}
@IBAction func buttonReset(_ sender: Any) {
}
// MARK: - ARSCNViewDelegate
/*
// Override to create and configure nodes for anchors added to the view's session.
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
return node
}
*/
func addBox() {
let node = SCNNode(geometry: SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0.0))
node.position = SCNVector3(0,0,-1)
node.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
sceneView.scene.rootNode.addChildNode(node)
}
func addRobot() {
let robotScene = SCNScene(named:"art.scnassets/frspbt.scn")
let robotNode = robotScene?.rootNode.childNode(withName: "frsbot", recursively: true)
robotNode?.position = SCNVector3(0.0,0.0,-1.0)
sceneView.scene.rootNode.addChildNode(robotNode!)
}
func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user
}
func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay
}
func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required
}
func animateNode(node: SCNNode) {
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = node.presentation.position
animation.toValue = SCNVector3(0,0, node.presentation.position.z - 1)
animation.autoreverses = true
node.addAnimation(animation, forKey: "position")
}
@objc func handleTap(sender: UITapGestureRecognizer) {
let sceneViewTappedOn = sender.view as! SCNView
let touchCoordinates = sender.location(in: sceneViewTappedOn)
let hitTest = sceneViewTappedOn.hitTest(touchCoordinates)
if hitTest.isEmpty {
print("outside of box")
} else {
let results = hitTest.first!
let geometry = results.node.geometry
// don't animate if an animation is already running
if results.node.animationKeys.isEmpty {
animateNode(node: results.node)
}
print(geometry ?? "default value")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment