下面的代码应将触摸坐标转换为SceneKit场景的世界坐标。
但是,如下面的输出所示,无论您在屏幕上的哪个位置(iPhone 5s),unprojectPoint
返回的点都会返回相同的点。
unprojectPoint
的班级文档建议使用介于0和1之间的Z值,但使用不同的值(如0.5)不会更改unprojectPoint
的输出。
This SO post讨论如何设置unprojectPoint
的深度值,但将Z值设置为大于1的值(例如,15,20)也不会更改输出。
在这两种情况下,从unprojectPoint
返回的X和Y值实际上也保持不变。
1)使用unprojectPoint
的正确方法是什么?
2)unprojectPoint
如何解释相机旋转?例如,如果您将相机移动到(0,20,0)并将相机向下旋转90度以使其面向地面,那么如何确保轮换?如果您设置深度为20并点击原点,则unprojectPoint
的所需返回值应为(0,0,0)。
3)如何让unprojectPoint
返回相机前面的值(例如,Z值低于相机的Z值)
代码:
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)")
}
输出:
2D点:(154.5,169.5)。 3D点:SCNVector3(x:-0.00111810782,y: 0.0232769605,z:7.9000001)
2D点:(280.5,252.0)。 3D点:SCNVector3(x:0.0244967155,y:0.00650534919,z:7.9000001)
2D点:(32.0,181.0)。 3D点:SCNVector3(x:-0.0260214079,y:0.0209390987,z:7.9000001)
2D点:(12.0,505.0)。 3D点:SCNVector3(x: -0.0300872531,y:-0.0449275821,z:7.9000001)
2D点:(311.5,12.5)。 3D点:SCNVector3(x:0.0307987742,y:0.0551938377,z:7.9000001)
2D点:(22.5,88.0)。 3D点:SCNVector3(x:-0.0279526841,y:0.0398452766,z:7.9000001)
2D点:(313.5,358.0)。 3D点:SCNVector3(x:0.0312053617,y:-0.0150436237,z:7.9000001)
2D点:(314.0,507.0)。 3D点:SCNVector3(x:0.0313070044,y:-0.0453341678,z:7.9000001)
2D点:(155.0,360.5)。 3D点:SCNVector3(x:-0.00101646129,y:-0.0155518558,z:7.9000001)
答案 0 :(得分:0)
只要您使用0和1,值就会更改unprojectPoint.
使用0代表Z值代表近平面上的点,而使用1代表远平面上的点。
因此,为了返回距离相机任意距离的场景点,我们开发了以下功能。我们是SceneKit的新手,所以请提供任何编辑或更正!
实际上,您可以定义近点和远点之间的光线/线,然后沿线选择一些点。
private func touchPointToScenePoint(recognizer: UIGestureRecognizer) -> SCNVector3 {
// Get touch point
let touchPoint = recognizer.locationInView(sceneView)
// Compute near & far points
let nearVector = SCNVector3(x: Float(touchPoint.x), y: Float(touchPoint.y), z: 0)
let nearScenePoint = sceneView.unprojectPoint(nearVector)
let farVector = SCNVector3(x: Float(touchPoint.x), y: Float(touchPoint.y), z: 1)
let farScenePoint = sceneView.unprojectPoint(farVector)
// Compute view vector
let viewVector = SCNVector3(x: Float(farScenePoint.x - nearScenePoint.x), y: Float(farScenePoint.y - nearScenePoint.y), z: Float(farScenePoint.z - nearScenePoint.z))
// Normalize view vector
let vectorLength = sqrt(viewVector.x*viewVector.x + viewVector.y*viewVector.y + viewVector.z*viewVector.z)
let normalizedViewVector = SCNVector3(x: viewVector.x/vectorLength, y: viewVector.y/vectorLength, z: viewVector.z/vectorLength)
// Scale normalized vector to find scene point
let scale = Float(15)
let scenePoint = SCNVector3(x: normalizedViewVector.x*scale, y: normalizedViewVector.y*scale, z: normalizedViewVector.z*scale)
print("2D point: \(touchPoint). 3D point: \(nearScenePoint). Far point: \(farScenePoint). scene point: \(scenePoint)")
// Return <scenePoint>
return scenePoint
}