Понимание непроектируемых координат SCNCamera - PullRequest
0 голосов
/ 27 декабря 2018

Я пытаюсь определить ширину в мировом координатном пространстве на разных глубинах Z SCNCamera.Насколько я понимаю, значение Z, равное 0 - это ближняя плоскость, а 1 - дальняя.

Опять же, я понимаю, что усеченный конус представляет собой перевернутую квадратную пирамиду, вершина которой находится в SCNCamera.

Что меня отталкивает, так это то, что ширина, которую я получаю, не линейна, а кажется экспоненциальной, когда я приближаюсь к Z = 1. Для меня это противоречит ментальной форме, которую я создаю в виде усеченного конуса в виде квадратной пирамиды.

Вот пример кода игровой площадки:

import UIKit
import SceneKit
import PlaygroundSupport

let scene = SCNScene()
let leftCamera = SCNCamera()
let leftCameraNode = SCNNode()

let boxGeometry = SCNBox(width: 10, height: 10, length: 10, chamferRadius: 1.0)
let box = SCNNode(geometry: boxGeometry)
box.position = SCNVector3(0,0,0)
scene.rootNode.addChildNode(box)

scene.rootNode.addChildNode(leftCameraNode)
leftCameraNode.position = SCNVector3(0, 0, 50)
leftCameraNode.eulerAngles = SCNVector3(0, 0, 0)
leftCameraNode.camera = leftCamera

let leftCameraView = SCNView(frame: CGRect(x: 0, y: 0, width: 700, height: 500))
PlaygroundPage.current.liveView = leftCameraView

leftCameraView.scene = scene
leftCameraView.autoenablesDefaultLighting = true
leftCameraView.pointOfView = leftCameraNode

var widths = [CGFloat : Float]()

func widthForDepth(_ depth: CGFloat) {
    let topLeftUnprojectedPoint = leftCameraView.unprojectPoint(SCNVector3(0, 0, depth))
    let topRightUnprojectedPoint = leftCameraView.unprojectPoint(SCNVector3(leftCameraView.bounds.width, 0, depth))
    let width = topRightUnprojectedPoint.x - topLeftUnprojectedPoint.x

    widths[depth] = width
}

widthForDepth(0)
widthForDepth(0.5)
widthForDepth(0.75)
widthForDepth(0.9)
widthForDepth(0.95)
widthForDepth(1)

Это дает мне следующие значения на разных глубинах: Z = 0 -> 1,61

Z = 0,5 -> 3,2

Z = 0,75 -> 6,2

Z = 0,9 -> 14,8

Z = 0,95 -> 27,1

Z = 1 -> 161,6

Насколько я понимаю, это значение для Z = 1 является правильным, однако другие значения не имеют смысла для меня.

Мой ящик имеет размер 10 единиц и подходит к экрану сзначение глубины камеры 0,5 (на расстоянии 50 единиц для камеры, у которой zFar равен 100 и zNear в 1).Но, тем не менее, он полностью виден на экране, когда вычисление без проекции говорит, что экран имеет ширину 3,2 единицы при 0,5.

Я знаю, что это простая проблема, но я смотрел на это несколько дней ине могу понять это.

1 Ответ

0 голосов
/ 31 декабря 2018

Что ж, получается, что моя исходная предпосылка была ошибочной.

Глубина камеры (измеренная между дальней плоскостью Z = 1 и ближней плоскостью Z = 0) не линейно пропорциональна мировому значению Z.

Поэтому я обнаружил, что сначала мне нужно использовать projectPoint, чтобы определить мировое значение Z по глубине камеры.

...