Jerry Chang
Jerry Chang

Reputation: 77

ARkit - Camera Position and 3D model Positions

I am trying to put several models in the scene.

for candidate in selectedCandidate {
    sceneView.scene.rootNode.addChildNode(selectedObjects[candidate])
}

The candidate and selectedCandidate stands for the index of the model I want to use. Each model contains a rootNode and nodes attached to it. I use the API worldPosition and position of SCNNode to get and modify 3D model's position.

The thing I want to do is put those models right in front users' eyes. It means I need to get the camera's position and orientation vector to put the models in the right position I want. I also use these codes to get the camera's position according to this solution https://stackoverflow.com/a/47241952/7772038:

guard let pointOfView = sceneView.pointOfView else { return }
let transform = pointOfView.transform
let orientation = SCNVector3(-transform.m31, -transform.m32, transform.m33)
let location = SCNVector3(transform.m41, transform.m42, transform.m43)

The PROBLEM is that the camera's position and the model's position I printed out directly are severely different in order of magnitude. Camera's position is 10^-2 level like {0.038..., 0.047..., 0.024...} BUT the model's position is 10^2 level like {197.28, 100.29, -79.25}. From my point of view when I run the program, I am in the middle of those models and models are very near, but the positions are so different. So can you tell me how to modify the model's position to whatever I want? I really need to put the model right in front of user's eyes. If I simply do addChildNode() the models are behind me or somewhere else, while I need the model just be in front of users' eyes. Thank you in advance!

Upvotes: 1

Views: 2021

Answers (1)

PongBongoSaurus
PongBongoSaurus

Reputation: 7385

If you want to place an SCNNode infront of the camera you can do so like this:

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

     guard let currentTransform = augmentedRealitySession.currentFrame?.camera.transform else { return }

     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

     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 = -3

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

}

And you can change any of the X,Y,Z values as you need.

Hope it points you in the right direction...

Update:

If you have multiple nodes e.g. in a scene, in order to use this function, it's probably best to create a 'holder' node, and then add all your content as a child.

Which means then you can simply call this function on the holder node.

Upvotes: 1

Related Questions