Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARKit interaction (gesture)

Tags:

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! :)

like image 654
spoax Avatar asked Jan 09 '18 15:01

spoax


People also ask

Which is better ARCore or ARKit?

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.

Does ARKit use LiDAR?

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.

Does ARKit work with front camera?

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.

Can you use ARKit With react native?

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.


1 Answers

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 
like image 182
Clay Avatar answered Sep 23 '22 12:09

Clay