P.M.
P.M.

Reputation: 73

ARKit - Placing objects in front of camera in portrait mode

When I use the transform from the current ARFrame to place an object in front of the camera, it seems to use landscape as the orientation of the device. Therefore if I hold the device in portrait and place an object it will appear tilted 90 degrees.

I would like the orientation of the object to be placed relative to portrait of the device instead. Is it possible to change this? Or do I have to rotate the anchor? And how would one do that?

Here is how I am creating the anchor:

@IBAction func add(_ sender: Any) {
    guard let currentFrame = self.sceneView.session.currentFrame else  { return }

    var translation = matrix_identity_float4x4
    translation.columns.3.z = -1

    let transform = currentFrame.camera.transform
    let anchorTransform = matrix_multiply(transform, translation)

    var anchor = ARAnchor(transform: anchorTransform)
    self.sceneView.session.add(anchor: anchor)
}

And below is how I am creating the node for rendering. Note that I have two child nodes in one parent node as I would like to be able to move these two nodes around as one.

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let childOne = SCNNode()
    childOne.geometry = SCNBox(width: 0.5, height: 0.1, length: 0.3, chamferRadius: 0)
    childOne.geometry?.firstMaterial?.diffuse.contents = UIColor.green

    let childTwo = SCNNode()
    childTwo.geometry = SCNBox(width: 0.2, height: 0.5, length: 0.1, chamferRadius: 0)
    childTwo.position = SCNVector3(0, 0.25, 0)
    childTwo.geometry?.firstMaterial?.diffuse.contents = UIColor.red

    let node = SCNNode()
    node.addChildNode(nodeOne)
    node.addChildNode(nodeTwo)

    return node
}

Update

Solved it by creating a rotation matrix for rotating Z-axis 90 degrees and then multiplied it with the translation matrix.

@IBAction func add(_ sender: Any) {
    guard let currentFrame = self.sceneView.session.currentFrame else  { return }

    var translation = matrix_identity_float4x4
    translation.columns.3.z = -1

    let transform = currentFrame.camera.transform

    let rotation = matrix_float4x4(SCNMatrix4MakeRotation(Float.pi/2, 0, 0, 1))

    let anchorTransform = matrix_multiply(transform, matrix_multiply(translation, rotation))

    var anchor = ARAnchor(transform: anchorTransform)
    self.sceneView.session.add(anchor: anchor)
}

Upvotes: 4

Views: 2098

Answers (1)

Goesta Bjoerling
Goesta Bjoerling

Reputation: 11

Portrait-vs-landscape seems to work automatically if you get the camera matrix via pointOfView

    let anchorTransform = pointOfView!.convertTransform(SCNMatrix4MakeTranslation(0, 0, -1),  to: nil)

Upvotes: 1

Related Questions