Getting the world space camera direction in SceneKit - ios

I have a camera node in my SceneKit scene that is setup to allow the user to orbit by offsetting it's pivot:
self.cameraNode.pivot = SCNMatrix4MakeTranslation(0, 0, -100);
The user then rotates the node to orbit the camera.
What I would like to work out is
A) how to get the world space direction the camera is facing at any given time
and then
B) how to convert that direction to x,y,z components I can use to move the camera node relative to the way the camera is facing (forward/back/left/right from the camera's perspective).
Thanks!

Related

ARKit how position nodes base on horizon and not the camera orientation?

When I add a new node with ARKit (ARSKView), the object is positioned base on the device camera. So if your phone is facing down or tilted, the object will be in that direction as well. How can I instead place the object base on the horizon?
For that, right after a new node's creation, use a worldOrientation instance property that controls the node's orientation relative to the scene's world coordinate space.
var worldOrientation: SCNQuaternion { get set }
This quaternion isolates the rotational aspect of the node's worldTransform matrix, which in turn is the conversion of the node's transform from local space to the scene's world coordinate space. That is, it expresses the difference in axis and angle of rotation between the node and the scene's rootNode.
let worldOrientation = sceneView.scene.rootNode.worldOrientation
yourNode.rotation = worldOrientation /* X, Y, Z, W components */
P.S. (as you updated your question) :
If you're using SpriteKit, 2D sprites you spawn in ARSKView are always face the camera. So, if the camera moves around a definite point of real scene, all the sprites must be rotated about their pivot point, still facing a camera.
Nothing can prevent you from using SceneKit and SpriteKit together.

Find distance between iOS Device Camera and user's face

I am trying to find distance between iOS device's front-facing camera and user's face in the real world.
So far, I have tried ARKit/SceneKit, and using ARFaceAnchor I am able to detect user's face distance from camera; but it works only in close proximity (up to about 88 cm). My application requires face distance detection up to 200 cms.
I am assuming this could be achieved without the use of trueDepth data (which is being used in ARFaceAnchor).
Can you put me in the right direction?
In order to get the distance between the device and the user's face you should convert position of the detected user's face into camera's coordinate system. To do this, you will have to use the convertPosition method from SceneKit to switch coordinate space, from face coordinate space to camera coordinate space.
let positionInCameraSpace = theFaceNode.convertPosition(pointInFaceCoordinateSpace, to: yourARSceneView.pointOfView)
theFaceNode is the SCNNode created by ARKit representing the user's face. The pointOfView property of your ARSCNView returns the node from which the scene is viewed, basically the camera.
pointInFaceCoordinateSpace could be any vertices of the face mesh or just the position of theFaceNode (which is the origin of the face coordinate system). Here, positionInCameraSpace is a SCNVector3, representing the position of the point you gave, in camera coordinate space. Then you can get the distance between the point and the camera using the x,y and z value of this SCNVector3 (expressed in meters).
these are some links that may help you :
-Distance between face and camera using ARKit
-https://github.com/evermeer/EVFaceTracker
-https://developer.apple.com/documentation/arkit/arfacetrackingconfiguration
-How to measure device distance from face with help of ARKit in iOS?

ARKit : Translate a 3D Object on camera view

I'm actualy developing an AR application on xCode with ARKit.
I have my iPad who is on a particular orientation and when I add a SCNode on (0,0,0) to my SCNScene with a ARWorldTrackingSessionConfiguration it appears in front of the camera when the iPad is perpendicular to the ground like so :
The iPad is perpendicular to the ground and the 3D object is at (0,0,0)
I would like to have my SCNode to appears directly on the iPad screen when I launch the ARScene like this :
The iPad is oriented in direction to the flower pot and i had to set the coordinates manually
How can i do that ?
I imagine i would have to do something like a translation of coordinates but I don't know how to do that.
And if it can help, i can have the distance between the camera and the flower pot
Thanks in advance ! :)
You need to pass the coordinates of the object in a SCNMatrix4 form as follows:
let translationMatrix = SCNMatrix4Translate(theNode.worldTransform, 0.1, 0.1, 0.1) //tx, ty, tz are translations in each axis i
and then theNode.transform = translation matrix

Scenekit object that stays in the center of the camera view (Swift)

So I have a camera in my SceneKit project that is able to rotate and move around freely, and I have an object that, in some cases, needs to stay at a constant distance away from the camera and always be in the center of its view no matter how the camera rotates. Unfortunately, I'm new to SceneKit and don't know how to accomplish this.
So the key things I'm looking for are:
How to have the object always at the same distance from the camera
How to have the object always be in the center of the camera's view no matter what direction it's looking
At the moment, both the camera and the object (an SCNNode with a box geometry) are children of the same scene.
I'm coding in swift so I'd prefer an answer using that, but if you have a solution in objective-c, that works too.
Thanks a bunch!
Think about how you might solve this in the real world. Grab a two by four of the appropriate length. Use duct tape to attach the ball to one end, and to attach the camera (aimed at the ball) to the other end.
Now you can carry that rig around with you. The ball will always be in the center of the camera view, and will be a constant distance away from the camera.
You can build the same rig, virtually, in SceneKit. Create a new SCNNode to be the rig (taking the place of the two by four). Add the ball as a child node, at (0, 0, 0). Add the camera as a child node too, at (0, 0, 5) (camera looks down the -Z axis, so this position should put the ball in the center of the view). Now you can move the rig node anywhere in the scene you want, and you'll have a consistent ball position.

SceneKit Moving a Camera around another Node

I would like to move the camera around a SCNNode nodeA.
What I'have done so far is:
self.cameraNode.constraints = [SCNLookAtConstraint(target: nodeA)]
now if I increment the position.x of the camera the camera still look toward the nodeA. How to move the camera around the nodeA (like the moon around the hearth)?
The camera should move along a circular orbit (just a circle, I'm not interested in elliptical orbit)
Add the moon as the child node of the earth. That way translating the earth won't affect the moon's relative position. You can find an example in the SceneKit Slides for WWDC 2014 sample code.

Resources