SceneKit 计算具有枢轴的节点的顶点世界坐标
Posted
技术标签:
【中文标题】SceneKit 计算具有枢轴的节点的顶点世界坐标【英文标题】:SceneKit calculate vertex world coordinates for node with pivot 【发布时间】:2017-11-30 08:06:44 【问题描述】:我正在使用 SceneKit 处理这个移动地图项目。 我制作了一个地球仪并旋转它的枢轴,使您当前的位置面向相机。 要在地图上投影一些文本,我需要计算一些世界坐标,我可以将其转换为屏幕坐标并发送到我的 overlaySKScene。 我没有成功使用 worldTransform 或 convertPosition/convertTransform 所以我想出了自己的计算:
import SceneKit
import simd
// a rotation-matrix which rotates the globe
// so 52º North, 4.75º East [Benelux] faces the camera @ [0,0,0]
let pivot = float4x4([
float4(0.996566, 0.0, -0.0828082, 0.0),
float4(-0.0652537, 0.615662, -0.785304, 0.0),
float4(0.0509818, 0.788011, 0.613547, 0.0),
float4(0.0, 0.0, 0.0, 1.0)
])
// position of Brussel in cartesian coordinates
let posBrussel = float4(0.0493100174, 0.776061833, 0.628726125, 1.0)
// setup globe
// apply scale & translation -> zoom in on Benelux
let zoom = Float(14.6193)
let distance = Float(-16.5852)
let node = SCNNode()
node.position = SCNVector3(0, 0, distance)
node.scale = SCNVector3(zoom, zoom, zoom)
node.pivot = SCNMatrix4(pivot)
// Manual calculation of world coordinates
let posBrusselScaled = zoom * posBrussel
let resultIntermediate = posBrusselScaled * pivot
let resultFinal = resultIntermediate + float4(0.0, 0.0, distance, 0.0)
// world coordinates Brussel
// resultFinal = float4(-0.0427321, -0.280209, -1.96864, 14.6193)
现在我希望有一种更简单的方法来计算这些世界坐标。就像将变换和枢轴相乘一样。
let transform = float4x4(node.transform)
posBrussel * pivot * transform // float4(-0.0427321, -0.280209, 14.6166, -15.5821)
posBrussel * transform * pivot // float4(-0.0427321, -0.280209, 14.6166, -9.42755)
虽然 x,y 值接近我自己的计算,但 z 值相差很远 [由于距离和缩放,它应该接近 -2]。
计算这些世界坐标的最佳/正确方法是什么?
【问题讨论】:
【参考方案1】:您不应该自己计算。 SceneKit 使用 convertPosition(_:, to:)
函数为您完成此任务。它允许您将坐标从本地节点的坐标系转换为其他节点的坐标系。
世界坐标的节点是rootNode
。
因此,考虑到posBrussel
是节点坐标空间中的位置,结果必须像
resultFinal = node.convertPosition(posBrussel, to: scene.rootNode)
screenPoint = sceneView.projectPoint(resultFinal)
【讨论】:
以上是关于SceneKit 计算具有枢轴的节点的顶点世界坐标的主要内容,如果未能解决你的问题,请参考以下文章
shader数学基础之顶点法向量从物体坐标系变换到世界坐标系