2017-08-25 16 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プレイグラウンドの例をGithubにアップロードしました。

+0

私はこれが同じ問題を抱えていると思います。球の半径は0.1mだが、カメラから1m離れているので、画面上では約30ptの高さと幅があるようだ。その球の_center_は正確ですが、その球の_bounding box_はまだワールド座標ですので、スクリーン空間に頂点を投影すると、あたかもカメラがノードから0mのように非常に誇張されています。 –

+0

これは投影行列に依存しますが、パースペクティブカメラ(renderer.pointOfView.camera.usesOrthographicProjection == false)を使用する場合、投影された境界ボックスは、カメラから遠い場合には小さくする必要があります。 – magicien

+0

また、ビューから別のレンダラーを選択することもできます。 SCNViewをSCNSceneRenderer(view.projectPoint(...))として使用できます。 – magicien

関連する問題