1
votes

So, I was able to put a box node at the anchors position. Now, how do I rotate the SCNNode in the scene?

I am trying to modify the node's transform & eulerAngles, but they have no effect:

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    print("nodeFor anchor \(anchor)")

    guard anchor.name == "card" else { return nil }

    let colors = [
        UIColor.yellow, // front
        UIColor.red, // right
        UIColor.blue, // back
        UIColor.green, // left
        UIColor.purple, // top
        UIColor.gray] // bottom

    let sideMaterials = colors.map { color -> SCNMaterial in
        let material = SCNMaterial()
        material.diffuse.contents = color
        material.locksAmbientWithDiffuse = true
        return material
    }

    let boxGeometry = SCNBox(width: 0.12, height: 0.01, length: 0.07, chamferRadius: 0)
    boxGeometry.materials = sideMaterials

    let node = SCNNode(geometry: boxGeometry)
    node.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
    node.eulerAngles.x = .pi / 2

    return node
}

I also tried to do the rotation in func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    node.eulerAngles.x = .pi / 2
}

But that didn't help as well.

I was successful in animating rotation with code below.

    let spin = CABasicAnimation(keyPath: "rotation")
    // Use from-to to explicitly make a full rotation around z
    spin.fromValue = NSValue(scnVector4: SCNVector4(x: 0, y: 0, z: 1, w: 0))
    spin.toValue = NSValue(scnVector4: SCNVector4(x: 0, y: 0, z: 1, w: Float(2 * Double.pi)))
    spin.duration = 3
    spin.repeatCount = 1
    node.addAnimation(spin, forKey: "rotation")

Based on that success, I also tried (but failed)

    node.rotation = SCNVector4(x: 5, y: 4, z: 3, w: 0)

Does anybody have a clue how I can rotate my node in the delegate methods of ARSCNViewDelegate ?

1

1 Answers

1
votes

The ARSession will position and orientate the node you vend to it. It's best to perform rotations on a child node to the one that is vended. So in func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode?

Prior to returning, you could say:

let node = SCNNode(geometry: boxGeometry)
node.eulerAngles = SCNVector3(x: -Float.pi / 2, y: 0, z: 0)

let rootNode = SCNNode()
rootNode.addChildNode(node)
return rootNode