如何将相机外部矩阵转换为SCNCamera位置和旋转

时间:2015-11-16 07:40:49

标签: ios opengl-es augmented-reality scenekit aruco

我试图用SceneKit来实现增强现实。

我使用ARuco(OpenCV增强现实库)通过估计标记的姿势获得了内在的相机矩阵和外在矩阵。

我使用内在矩阵(fovy,aspect,zNear,zFar)的参数设置SCNCamera' projectionTransform

通常在OpenGL中,相对于相机坐标的世界坐标是使用ModelView计算的,但在SceneKit中,没有像modelView那样的东西。

所以我计算了外在矩阵的逆矩阵,得到相对于世界坐标的相机坐标(标记坐标)。

我认为我通过包含旋转和平移矩阵的逆矩阵得到了正确的相机位置。

但是我无法从相机那里获得轮换

你有什么想法吗?

2 个答案:

答案 0 :(得分:6)

SceneKit具有与您在OpenGL中遇到的相同的视图矩阵,在您开始使用着色器之前,它们只是隐藏一些。有点太隐蔽的IMO。

你似乎已经找到了大部分内容。投影矩阵来自您的相机projectionTransform,视图矩阵来自相机矩阵SCNMatrix4Invert(cameraNode.transform)的倒数。在我的例子中,一切都在世界坐标中,使我的模型矩阵成为一个简单的单一矩阵。

我最终使用的代码来获得经典的模型 - 视图 - 投影矩阵就像......

let projection = camera.projectionTransform()
let view = SCNMatrix4Invert(cameraNode.transform)
let model = SCNMatrix4Identity

let viewProjection = SCNMatrix4Mult(view, projection)
let modelViewProjection = SCNMatrix4Mult(model, viewProjection)

出于某种原因,我发现SCNMatrix4Mult(...)以不同于我期望的顺序接受了参数(例如;与GLKMatrix4Multiply(...)相反)。

我仍然不是100%,所以欢迎编辑/提示。使用这种方法,我无法获得SceneKit MVP矩阵(传递给着色器)以匹配上面代码计算的...但它足够接近我所需要的。

答案 1 :(得分:2)

@lock的回答看起来很不错,只有几个补充:

(1)访问SCNNode worldTransform而不是变换,以防cameraNode动画或为父对象:

let view = SCNMatrix4Invert(cameraNode.presentationNode.worldTransform)

(2)代码不考虑视图的宽高比。例如,假设透视投影,你会想要:

perspMatrix.m11 /= viewportAR; //if using Yfov -> adjust Y`
/* or, */
perspMatrix.m22 *= viewportAR; //if using Xfov -> adjust X`

其中,viewportAR = viewport.width / viewport.height

另一种方法是在场景中有一个带有渲染委托的节点,并从该委托中检索SceneKit的矩阵(它们作为选项传递):

FOUNDATION_EXTERN NSString * const SCNModelTransform;
FOUNDATION_EXTERN NSString * const SCNViewTransform;
FOUNDATION_EXTERN NSString * const SCNProjectionTransform;
FOUNDATION_EXTERN NSString * const SCNNormalTransform;
FOUNDATION_EXTERN NSString * const SCNModelViewTransform;
FOUNDATION_EXTERN NSString * const SCNModelViewProjectionTransform;