I have a SCNScene. Inside it, I have a mesh (SCNNode) and another SCNNode with SCNCamera.
let sceneView = SCNView()
let scene = SCNScene()
let meshNode: SCNNode()
lazy var cameraNode: SCNNode = {
let node = SCNNode()
let camera = SCNCamera()
node.camera = camera
return node
}()
User can rotate the camera to see around. Whenever I want, I need to be able to get coordinates of point of mesh, the camera is looking at, and normal vector at this point.
I want to explain more simply. So imagine, the camera points a laser ray in front of itself (in the direction it looks). And this ray hit the mesh. I need the coordinates of this point (where the ray hit the mesh). And a normal vector at this point.
Basically, what I need is similar to information which SCNHitTestResult provides:
let hitResults = sceneView.hitTest(touchPoint, options: [:])
if let result: SCNHitTestResult = hitResults.first {
let localCoordinates = result.localCoordinates
let localNormal = result.localNormal
}
How can I get localCoordinates and localNormal of a point on the mesh the camera is looking at?
Solved!
with the help of @mnuages and this answer https://stackoverflow.com/a/42034883/19433422 I solved problem:
func sceneSpacePosition(inFrontOf node: SCNNode, atDistance distance: Float) -> SCNVector3 {
let localPosition = SCNVector3(x: 0, y: 0, z: Float(CGFloat(-distance)))
let scenePosition = node.convertPosition(localPosition, to: nil)
return scenePosition
}
let to: SCNVector3 = sceneSpacePosition(inFrontOf: cameraNode, atDistance: Float(radius))
if let hitTest = scene.rootNode.hitTestWithSegment(from: cameraNode.position, to: to, options: .none).first {
let localCoordinates = hitTest.localCoordinates
let localNormal = hitTest.localNormal
}
You can use [SCNNode hitTestWithSegmentFromPoint:toPoint:options:]
to achieve that.
Alternatively, if the camera is the current point of view then a hit test at the middle of the SCNView
achieves what you want.