The code below should translate touch coordinates into world coordinates for a SceneKit scene.
However, as illustrated by the output below, the point returned by unprojectPoint
returns effectively the same point no matter where you touch on the screen (iPhone 5s).
The class docs for unprojectPoint
suggest using Z values between 0 and 1, but using different values like 0.5 did not change the output for unprojectPoint
.
This SO post discusses how to set the depth value for unprojectPoint
, but setting the Z value to values greater than 1 (e.g., 15, 20) also did not change the output.
In both cases, the X and Y values return from unprojectPoint
effectively remained the same as well.
1) What is the right way to use unprojectPoint
?
2) How does unprojectPoint
account for camera rotations? For instance, if you moved the camera to (0, 20, 0) and rotated the camera down 90 degrees so it's facing the ground, how do you ensure the rotation is accounted for? If you set a depth of 20 and tapped on the origin, the desired return value from unprojectPoint
should be (0, 0, 0).
3) How do you get unprojectPoint
to return values in front of the camera (e.g., Z values are lower than the camera's Z value)
Code:
cameraNode.position = SCNVector3(x: 0, y: Float(0), z: Float(8))
func sceneViewTapped(recognizer: UITapGestureRecognizer) {
let point = recognizer.locationInView(sceneView)
let unprojectPoint = SCNVector3(x: Float(point.x), y: Float(point.y), z: 0.0)
let scenePos = sceneView.unprojectPoint(unprojectPoint)
print("2D point: \(point). 3D point: \(scenePos)")
}
Output:
2D point: (154.5, 169.5). 3D point: SCNVector3(x: -0.00111810782, y: 0.0232769605, z: 7.9000001)
2D point: (280.5, 252.0). 3D point: SCNVector3(x: 0.0244967155, y: 0.00650534919, z: 7.9000001)
2D point: (32.0, 181.0). 3D point: SCNVector3(x: -0.0260214079, y: 0.0209390987, z: 7.9000001)
2D point: (12.0, 505.0). 3D point: SCNVector3(x: -0.0300872531, y: -0.0449275821, z: 7.9000001)
2D point: (311.5, 12.5). 3D point: SCNVector3(x: 0.0307987742, y: 0.0551938377, z: 7.9000001)
2D point: (22.5, 88.0). 3D point: SCNVector3(x: -0.0279526841, y: 0.0398452766, z: 7.9000001)
2D point: (313.5, 358.0). 3D point: SCNVector3(x: 0.0312053617, y: -0.0150436237, z: 7.9000001)
2D point: (314.0, 507.0). 3D point: SCNVector3(x: 0.0313070044, y: -0.0453341678, z: 7.9000001)
2D point: (155.0, 360.5). 3D point: SCNVector3(x: -0.00101646129, y: -0.0155518558, z: 7.9000001)