我有这个应用程序,只适用于横向。
我在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视图时,我在左下方看到了一个视图!!
就像我说应用程序仅在横向操作,但这些坐标系统都是混乱的。
答案 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 ... 无论如何:问题解决了: - )