[英]SceneKit: unprojectPoint returns same/similar point no matter where you touch screen
下面的代碼應將觸摸坐標轉換為SceneKit場景的世界坐標。
但是,如下面的輸出所示,無論您在屏幕上的哪個位置(iPhone 5s), unprojectPoint
返回的點都會返回相同的點。
unprojectPoint
的類文檔建議使用介於0和1之間的Z值,但使用不同的值(如0.5)不會更改unprojectPoint
的輸出。
這篇SO文章討論了如何設置unprojectPoint
的深度值,但是將Z值設置為大於1的值(例如, unprojectPoint
)也沒有改變輸出。
在這兩種情況下,從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和1, unprojectPoint.
的值就會發生變化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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.