簡體   English   中英

SceneKit:無論你在哪里觸摸屏幕,unprojectPoint都會返回相同/相似的點

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM