I am trying to make an iOS app using ARKit. So far I have used the "placing objects" example by Apple and augmented it so it has my own geometry. This part all works great.
I have several different objects that can be placed on the ground. To explain the objects in simple terms, they are boxes with doors on the front of them.
The problem I have is that I now want to add gestures to the app so when the door is tapped it rotates open. And then when it is tapped again the door closes.
I have looked for some tutorial on how to do this but couldn't find anything. Can someone explain to me how to do this or point me to a tutorial showing how to achieve this interactivity.
Thank you! :)
Both kits have their strengths. For example, ARKit is better for image recognition and specific iOS tasks, while ARCore is better for general graphics manipulation and gaming. However, both are widely used and will continue to develop alongside the hardware they serve.
Overview. On a fourth-generation iPad Pro running iPad OS 13.4 or later, ARKit uses the LiDAR Scanner to create a polygonal model of the physical environment.
Regarding the front-facing camera: in short, no. ARKit offers two basic kinds of AR experience: World Tracking ( ARWorldTrackingConfiguration ), using the back-facing camera, where a user looks "through" the device at an augmented view of the world around them.
Here's what you need to make a tasty AR snack: A computer with internet access. An iOS device that sports the A9 chip (iPhone 6S and up; iPads from 2017+) and is running iOS 11+ (if you have an iPhone, it's probably good enough). Android is not currently supported.
Below is a basic swift Playground which creates a door at loading. By tapping on the door you can rotate open, tapping again will close the door. I’ve broken the code up into different functions so you can see how the door opens & then closes.
import ARKit
import SceneKit
import PlaygroundSupport
class ViewController: NSObject {
var doorNode: SCNNode!
var doorisOpen: Bool!
var sceneView: ARSCNView
init(sceneView: ARSCNView) {
self.sceneView = sceneView
super.init()
self.setupWorldTracking()
self.sceneView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(_:))))
// place door
self.sceneView.scene.rootNode.addChildNode(createDoor(position: SCNVector3(0,0,-1)))
}
private func setupWorldTracking() {
if ARWorldTrackingConfiguration.isSupported {
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
configuration.isLightEstimationEnabled = true
self.sceneView.session.run(configuration, options: [])
}
}
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
let results = self.sceneView.hitTest(gesture.location(in: gesture.view), types: ARHitTestResult.ResultType.featurePoint)
guard let result: ARHitTestResult = results.first else {
return
}
let tappedNode = self.sceneView.hitTest(gesture.location(in: gesture.view), options: [:])
if !tappedNode.isEmpty {
let node = tappedNode[0].node
if doorisOpen == true {
// rotate door
closeDoor()
} else {
// rotate door
openDoor()
}
} else {
return
}
}
func createDoor(position: SCNVector3) -> SCNNode {
let door = SCNBox(width: 0.3, height: 0.7, length: 0.025, chamferRadius: 0)
doorNode = SCNNode(geometry: door)
door.firstMaterial?.locksAmbientWithDiffuse = true
door.firstMaterial?.diffuse.contents = UIColor.brown
// place door
doorNode.position = position
// Pivot door from the end
endPivot(for: doorNode)
return doorNode
}
func openDoor() {
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(degToRadians(degrees: 90)), z: 0, duration: 1)
doorNode.runAction(rotate)
doorisOpen = true
}
func closeDoor() {
let rotate = SCNAction.rotateBy(x: 0, y: CGFloat(degToRadians(degrees: -90)), z: 0, duration: 1)
doorNode.runAction(rotate)
doorisOpen = false
}
func endPivot(for node: SCNNode) {
var min = SCNVector3Zero
var max = SCNVector3Zero
node.__getBoundingBoxMin(&min, max: &max)
node.pivot = SCNMatrix4MakeTranslation(min.x, 0, 0)
}
func degToRadians(degrees:Double) -> Double
{
return degrees * (M_PI / 180);
}
}
let sceneView = ARSCNView()
let viewController = ViewController(sceneView: sceneView)
sceneView.autoenablesDefaultLighting = true
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = viewController.sceneView
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With