0

I'm very new to ARKit (2 days old to be precise) and I'm trying to place a node on my ARSCNView when tapping and I am able to successfully do so 50% of the time. The other half of the time, nothing appears on screen. I've narrowed it down to the following line of code:

func getCameraTransform(for camera: ARCamera) -> MDLTransform {
        return MDLTransform(matrix: camera.transform)
    }

When nothing is appearing on screen, the above function is returning a transform.translation of float3(0.0, 0.0, 0.0)

I've checked and the camera.transform is providing a value that looks like simd_float4x4([[0.98134, 0.0198354, -0.191256, 0.0)], [-0.0129627, 0.999227, 0.0371193, 0.0)], [0.191844, -0.0339474, 0.980838, 0.0)], [-0.482363, -0.00405288, -0.768801, 1.0)]]) transform.translation is 0.

Why does this return 0 sometimes but work perfectly fine other times I tap?

Here is the full code:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard touches.first!.tapCount == 1 else { return }
        let camera = sceneView.session.currentFrame!.camera

    let transform = getCameraTransform(for: camera)
    let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    let cube = SCNNode(geometry: boxGeometry)
// SOMETIMES TRANSFORM.TRANSLATION IS JUST 0s
        let position = SCNVector3(
            transform.translation.x,
            transform.translation.y,
            transform.translation.z
            )
        cube.position = position
        sceneView.scene.rootNode.addChildNode(cube)
    }

func getCameraTransform(for camera: ARCamera) -> MDLTransform {
        return MDLTransform(matrix: camera.transform) // this is returning the 0 translation every other time
    }
Alan Scarpa
  • 3,352
  • 4
  • 26
  • 48

1 Answers1

0

I think it may be better to look at a different way to approach the issue. I haven't seen that example before and from having a test, it doesn't seem to be what you need.

As such, I will provide you with a few examples which should help you get started.

(1) Place An Object At A Certain Position Based On The Current Frame Of The Camera:

/// Adds An SCNNode 3m Away From The Current Frame Of The Camera
func addNodeInFrontOfCamera(){

 //1. Get The Current Frame Of The Camera
 guard let currentTransform = augmentedRealitySession.currentFrame?.camera.transform else { return }

 //2. Create An SCNNode
 let nodeToAdd = SCNNode()
 let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
 boxGeometry.firstMaterial?.diffuse.contents = UIColor.red
 nodeToAdd.geometry = boxGeometry

 // Create A Transform With A Translation 1m In Front Of The Camera
 var translation = matrix_identity_float4x4

 //Change The X Value
 translation.columns.3.x = 0

 //Change The Y Value
 translation.columns.3.y = 0

 //Change The Z Value
 translation.columns.3.z = -1

nodeToAdd.simdTransform = matrix_multiply(currentTransform, translation)
augmentedRealityView?.scene.rootNode.addChildNode(nodeToAdd)

}

(2) Place an SCNNode Based On Any Available featurePoints In The Scene:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //1. Get The Current Touch Point
    guard let currentTouchPoint = touches.first,
        //2. Perform A Hit Test Against Any Feature Points
        let result = augmentedRealityView.hitTest(currentTouchPoint.location(in: augmentedRealityView), types: .featurePoint).last else { return }

    //3. Get The World Coordinates Of The Result
    let transform = SCNMatrix4(result.worldTransform)

    //4. Get The Positional Data From The Transform
    let vectorFromTransform = SCNVector3(transform.m41, transform.m42, transform.m43)

    //5. Create An SCNBox At The Point
    let boxNode = SCNNode()
    let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    boxNode.geometry = boxGeometry
    boxNode.position = vectorFromTransform
    augmentedRealityView.scene.rootNode.addChildNode(boxNode)

}

Apologies if it doesn't explain the results your are experiencing, but nonetheless, I hope it helps...

BlackMirrorz
  • 7,217
  • 2
  • 20
  • 31
  • This is really helpful! How can the code be modified for the box to be placed where the user taps the screen regardless of feature points? For example, if I tap the screen while looking at a blank white wall, I'd like the box to have the X and Y coordinates of the tap, and then a hard-coded Z value of -0.8 for example. Is this possible? – Alan Scarpa Mar 28 '18 at 01:55
  • Alan please check this: https://stackoverflow.com/questions/25150737/how-to-use-ios-swift-scenekit-scnscenerenderer-unprojectpoint-properly & Look At Crashalot's Answer :) – BlackMirrorz Mar 28 '18 at 03:06