1
votes

I want to add a node to my scene, keeping a position in relation to the camera, but keeping the orientation/rotation of the scene. Where I'm up to so far...

When I tap the screen, I add an anchor to my scene, with a transform equal to the camera's transform. Then in didUpdateNode, which is when the anchor node has its' positional information setup, I add a child node containing a model, which has position.z = -0.5. The model node is added to the scene directly in front of the camera, and mirrors the rotational properties of the camera. With the phone tilted downwards and at an angle, this might look like so:

enter image description here

The model node, affected by the rotational data of the anchor node, is rotated in the same way as the camera. This particular model appears on its side - I'm not concerned about that, it's just a placeholder. Also ignore the red button at the top, that was for debugging.

So far, so good.

What I want to happen instead of this is for the rotational information to essentially be "reset", so it instead appears at the same height as my camera, and facing a default face-forward position. And if I were to rotate the camera differently and move around the room, additional models would be added at differing positions, but still at the same height and with the same orientation.

That might look something like this. Imagine that I've just tapped the screen to add the object, and it appears at a standard height, and rotation relevant to the scene, rather than the camera.

enter image description here

I've tried playing around with the node's eulerAngles, rotation and orientation properties but can't get this to work satisfactorily. Here's the code I have so far.. I've created a blank scene, and I'm using ship.scn from the standard SceneKit project as the model:

class ViewController: UIViewController, ARSCNViewDelegate {
  @IBOutlet var sceneView: ARSCNView!

  var anchors = [ARAnchor]()    

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the view's delegate
    sceneView.delegate = self

    // Show statistics such as fps and timing information
    sceneView.showsStatistics = true

    // Create a new scene
    let scene = SCNScene(named: "scene.scn")!

    // Set the scene to the view
    sceneView.scene = scene
  }

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Create a session configuration
    let configuration = ARWorldTrackingSessionConfiguration()
    configuration.planeDetection = .horizontal

    // 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()
  }

  func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    if anchors.contains(anchor) {
        // Create a new scene
      let scene = SCNScene(named: "art.scnassets/ship.scn")!
      let shipNode = scene.rootNode.childNode(withName: "ship", recursively: true)!
      shipNode.position.z = -5
      node.addChildNode(shipNode)
    }

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

        if let currentFrame = sceneView.session.currentFrame {
        let translation = matrix_identity_float4x4
        let transform = simd_mul(currentFrame.camera.transform, translation)
        let anchor = ARAnchor(transform: transform)

        anchors.append(anchor)
        sceneView.session.add(anchor: anchor)
        }
    }
  }
}
1
Concerning the model position: what exactly do you want to be reset? Do you want that the plane appears at your camera height ? At a fixed constant height? That the plane appears always north to your camera ? In front of the camera on ? Concerning the model orientation: do you want it to have a constant one unrelated to the camera (like always north, always vertical) or a mix (like always face the camera, always vertical) ?Guig
Maybe take a look into SCNTransformConstraint.jlsiewert
@Guig Ideally, I want a flat plane to created in the world, where the z coordinate would travel south to north and x coodinate west to east, so in my initial node I'm trying to create that. I did leave out the details of getting the plane to align with North, because that involves Core Location and it's the next step. Right now I just need it to be, in laymans terms, flat and non-rotated, as if it were sitting straight up on the floor.Andrew

1 Answers

0
votes

Am I missing something or do you just want each model to have the same orientation, irrespective of camera orientation?

In which case can you just set each models orientation to be the same as a node added when the session began running?

I.e when the session begins you add a node to the scene (visible or hidden), save its orientation, then use that again later on?