2017-08-25 55 views
0

我有一個SCNSphere,我想在屏幕像素(或更準確地說,點)中獲得它的投影大小。如何以像素爲單位計算SCNNode的大小?

我認爲這將做到這一點:

let bounds = endNode.boundingBox 
let projectedMin = renderer.projectPoint(bounds.min) 
let projectedMax = renderer.projectPoint(bounds.max) 
let sizeInPts = CGSize(width: CGFloat(projectedMax.x - projectedMin.x), height: CGFloat(projectedMax.y - projectedMin.y)) 

但是不起作用。 sizeInPts的寬度和高度始終沒有問題。

+0

...這很清楚爲什麼上述不起作用。從世界單位座標到屏幕座標時,用projectPoint投影_bounds_將被誇大。但仍然不確定正確的做法是什麼。 –

回答

2

我想你應該檢查邊界框的所有頂點。
我沒有測試這段代碼,但我希望它能正常工作。

let (localMin, localMax) = endNode.boundingBox 
let min = endNode.convertPosition(localMin, to: nil) 
let max = endNode.convertPosition(localMax, to: nil) 
let arr = [ 
    renderer.projectPoint(SCNVector3(min.x, min.y, min.z)), 
    renderer.projectPoint(SCNVector3(max.x, min.y, min.z)), 
    renderer.projectPoint(SCNVector3(min.x, max.y, min.z)), 
    renderer.projectPoint(SCNVector3(max.x, max.y, min.z)), 
    renderer.projectPoint(SCNVector3(min.x, min.y, max.z)), 
    renderer.projectPoint(SCNVector3(max.x, min.y, max.z)), 
    renderer.projectPoint(SCNVector3(min.x, max.y, max.z)), 
    renderer.projectPoint(SCNVector3(max.x, max.y, max.z)) 
] 
let minX: CGFloat = arr.reduce(CGFloat.infinity, { $0 > $1.x ? $1.x : $0 }) 
let minY: CGFloat = arr.reduce(CGFloat.infinity, { $0 > $1.y ? $1.y : $0 }) 
let minZ: CGFloat = arr.reduce(CGFloat.infinity, { $0 > $1.z ? $1.z : $0 }) 
let maxX: CGFloat = arr.reduce(-CGFloat.infinity, { $0 < $1.x ? $1.x : $0 }) 
let maxY: CGFloat = arr.reduce(-CGFloat.infinity, { $0 < $1.y ? $1.y : $0 }) 
let maxZ: CGFloat = arr.reduce(-CGFloat.infinity, { $0 < $1.z ? $1.z : $0 }) 

let width = maxX - minX 
let height = maxY - minY 
let depth = maxZ - minZ 

let sizeInPts = CGSize(width: width, height: height) 

我將Xcode Playground示例上傳到Github

+0

我認爲這遭受同樣的問題。想象一下,球體半徑爲1米,但距離相機1米遠,所以在屏幕上它看起來高約30尺高。投影到屏幕座標中的該球體的_center_將是準確的,但該球體的_bounding box_仍處於世界座標中,所以當您將頂點投影到屏幕空間時,會得到非常誇張的東西,就好像相機距離節點0m。 –

+0

它取決於投影矩陣,但如果使用透視攝像機(renderer.pointOfView.camera.usesOrthographicProjection == false),則投影邊界框應遠離相機。 – magicien

+0

或者您可以從視圖中選擇不同的渲染器。您可以使用SCNView作爲SCNSceneRenderer(view.projectPoint(...)) – magicien

相關問題