如何将SCNVector3位置转换为CGPoint SCNView坐标?

时间:2016-05-29 21:08:39

标签: ios iphone scenekit cgpoint scnvector3

我有这个应用程序,只适用于横向。

我在scenekit上有一个对象。该对象位于某个位置,由:

指定
 SCNNode * buttonRef = [scene.rootNode childNodeWithName:@"buttonRef" recursively:YES];
 SCNVector3 buttonRefPosition = [buttonRef position];

现在我需要将SCNVector3转换为mainView 2D坐标,其中

 mainView = (SCNView *)self.view;

场景是使用正交相机,所以没有视角。相机是默认相机。没有轮换,没有翻译。相机的orthographicScale是5.4。

如何转换?

我在SO上找到了关于反向问题的其他答案,即从CGPoint转换为SCNVector3,但对于我来说,从SCNVector3到CGPoint的反转方式听起来并不明显。

如果SCNView是UIView的子类,则(0,0)是左上角,而对于iPhone 6格局,(667,375)是右下角。

我的这个按钮几乎是正确的中间高度。就UIKit而言,我会说这个按钮位于(600,187)但是当我这样做时:

SCNNode * buttonRef = [scene.rootNode childNodeWithName:@"buttonRef" recursively:YES];
SCNVector3 buttonRefPosition = [buttonRef position];

SCNVector3 projectedPoint = [mainView projectPoint: buttonRefPosition];

我将projectPoint等于(7.8,375,0)(?)

当我使用UIKit向坐标(7.8,375)添加10x10视图时,我在左下方看到了一个视图!!

就像我说应用程序仅在横向操作,但这些坐标系统都是混乱的。

2 个答案:

答案 0 :(得分:4)

将模型空间点转换为屏幕空间点称为投影(因为它将相机的投影变换应用于从3D空间映射到2D空间)。渲染器(通过GPU)每帧执行很多次,以将场景中的点数放到屏幕上。

当您需要自己动手时,还有一种方便的方法:projectPoint:

答案 1 :(得分:3)

相当古老的问题,但遗憾的是@ricksters的答案对我来说并没有什么帮助,因为 projectPoint:在我的情况下仍然提供混乱的视图坐标(与@SpaceDog描述的问题相同)! / p>

然而,我发现,在我的情况中,问题是,我已经将变换应用到我的根节点(将世界颠倒了;-))。这显然会导致 projectPoint: ...

的错误结果

由于无法删除转换,因此我必须将输入调整为 projectPoint:

SCNVector3  viewStartPosition = ...; // Some place in the scene
SCNVector3  viewStartPositionRel = SCNVector3FromSCNVector4(SCNMatrix4MultV(self.scene.rootNode.worldTransform, SCNVector4FromSCNVector3(viewStartPosition)));
// Vector from UISceneView 0/0 top/left to start point
SCNVector3  viewStartPositionInViewCoords = [self.sceneView projectPoint:viewStartPositionRel];

不幸的是,Apple没有为SCNMatrix4矩阵提供矩阵数学,所以使用的(非常简单的)矩阵处理方法也是“自制的”:

/*
 SCNVector4FromSCNVector3

 */
SCNVector4 SCNVector4FromSCNVector3(SCNVector3 pV) {
    return SCNVector4Make(pV.x, pV.y, pV.z, 0.0);
}

/*
 SCNVector3FromSCNVector4

 */
SCNVector3 SCNVector3FromSCNVector4(SCNVector4 pV) {
    return SCNVector3Make(pV.x, pV.y, pV.z);
}

/*
 SCNMatrix4MultV

 */
SCNVector4 SCNMatrix4MultV(SCNMatrix4 pM, SCNVector4 pV) {
    SCNVector4  r = {
        pM.m11 * pV.x + pM.m12 * pV.y + pM.m13 * pV.z + pM.m14 * pV.w,
        pM.m21 * pV.x + pM.m22 * pV.y + pM.m23 * pV.z + pM.m24 * pV.w,
        pM.m31 * pV.x + pM.m32 * pV.y + pM.m33 * pV.z + pM.m34 * pV.w,
        pM.m41 * pV.x + pM.m42 * pV.y + pM.m43 * pV.z + pM.m44 * pV.w
    };
    return r;
}

我不知道,如果这是SceneKit中的错误,或者是否禁止将转换应用于rootNode ... 无论如何:问题解决了: - )

相关问题