2016-09-10 6 views
1

아래 코드는 터치 좌표를 SceneKit 장면의 세계 좌표로 변환해야합니다.SceneKit : unprojectPoint가 화면을 터치 한 위치와 상관없이 동일하거나 유사한 점을 반환합니다.

그러나 아래 출력에서 ​​설명한 것처럼 unprojectPoint에 의해 반환 된 지점은 화면 (iPhone 5s)을 터치 한 위치와 관계없이 사실 동일한 지점을 반환합니다.

unprojectPoint의 클래스 문서는 0과 1 사이의 Z 값을 사용하도록 제안하지만 0.5와 같은 다른 값을 사용하면 unprojectPoint의 출력이 변경되지 않습니다.

This SO postunprojectPoint에 대해 깊이 값을 설정하는 방법을 설명하지만 Z 값을 1보다 큰 값 (예 : 15, 20)으로 설정하면 출력이 변경되지 않습니다.

두 경우 모두 X 및 Y 값은 unprojectPoint에서 효과적으로 동일하게 유지됩니다.

1) unprojectPoint을 사용하는 올바른 방법은 무엇입니까?

2) unprojectPoint은 카메라의 회전을 어떻게 설명합니까? 예를 들어, 카메라를 (0, 20, 0)으로 이동하고 카메라를 90도 회전시켜 땅을 마주 보게되면 회전이 어떻게 처리되는지 확인하십시오. 깊이를 20으로 설정하고 원점에서 탭한 경우 unprojectPoint의 원하는 반환 값은 (0, 0, 0)이어야합니다. 카메라 앞에 값을 반환 unprojectPoint을 얻는 방법

3) (예를 들어, 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)") 
} 

출력 :

2 점 : (154.5, 169.5). 3D 포인트 : SCNVector3 (x : -0.00111810782, y : 0.0232769605, z : 7.9000001)

2 포인트 : (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)

2 포인트 : (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)

2 포인트 : (313.5, 358.0). 3D 포인트 : SCNVector3 (x : 0.0312053617, y : -0.0150436237, z : 7.9000001)

2 포인트 : (314.0, 507.0). 3D 포인트 : SCNVector3 (x : 0.0313070044, y : -0.0453341678, z : 7.9000001)

2 점 : (155.0, 360.5). 3D 점 : SCNVector3 (x : -0.00101646129, y : -0.0155518558, z : 7.9000001)

답변

0

0과 1을 사용하는 한 값은 unprojectPoint.에 대해 변경됩니다. Z 값으로 0을 사용하면 가까운 평면에있는 점을 나타내고 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 
} 
+0

이 문제가 해결 되었습니까? 나는 같은 문제에 직면 해있다. –