SceneKit 计算具有枢轴的节点的顶点世界坐标

Posted

技术标签:

【中文标题】SceneKit 计算具有枢轴的节点的顶点世界坐标【英文标题】:SceneKit calculate vertex world coordinates for node with pivot 【发布时间】:2017-11-30 08:06:44 【问题描述】:

我正在使用 SceneKit 处理这个移动地图项目。 我制作了一个地球仪并旋转它的枢轴,使您当前的位置面向相机。 要在地图上投影一些文本,我需要计算一些世界坐标,我可以将其转换为屏幕坐标并发送到我的 overlaySKScene。 我没有成功使用 worldTransformconvertPosition/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 计算具有枢轴的节点的顶点世界坐标的主要内容,如果未能解决你的问题,请参考以下文章

使用SceneKit控制飞行车辆的运动

顶点法向量从物体坐标系变换到世界坐标系

shader数学基础之顶点法向量从物体坐标系变换到世界坐标系

在纹理的SceneKit绘画与纹理坐标

SceneKit:如何将节点的移动限制在本地的一个轴上,而不是整个世界

如何在代码中创建 SceneKit SCNSkinner 对象?