你正在经历经典的“我在矩阵上做错了什么”行为,需要大量的反复试验才能解决。我还认为您一直在 Vuforia 网站上阅读内容,但这些内容几乎没有任何帮助。 :)
重新排列矩阵可能是你出错的地方。这SCNMatrix
应该直接与OpenGL兼容。我实际上把一切都投入了simd::matrix4x4
并使用内置的SCNMatrix4FromMat4
将它们转换为SCNMatrix
.
SceneKit 使用矩阵来表示坐标空间变换,
反过来又可以表示组合位置、旋转或
三维空间中物体的方向和比例。
SceneKit 矩阵结构按行优先顺序排列,因此它们是
适合传递给着色器程序或接受的 OpenGL API
矩阵参数。
所以,总结一下......我相信你应该删除:
SCNMatrix4 inverted = SCNMatrix4Invert(extrinsic);
至于复制GLMatrix
to an SCNMatrix
,无需尝试,应该是正确的。将使用您的方法生成的投影矩阵的结果与我的方法进行比较。它们应该是相同的。
投影矩阵
我得到这样的投影矩阵:
const Vuforia::Matrix44F projectionMatrix = Vuforia::Tool::getProjectionGL(cameraCalibration, nearPlane, farPlane);
simdMatrixWithVuforiaMatrix44F(projectionMatrix);
我将矩阵转换为simd::matrix4x4
(我在 C++ 领域花费了大量时间)这只是 SceneKit 支持的 Apple 定义的结构。
#include <simd/simd.h>
matrix_float4x4 simdMatrixWithVuforiaMatrix44F(const Vuforia::Matrix44F &matrix)
{
vector_float4 col0 = { matrix.data[0], matrix.data[1], matrix.data[2], matrix.data[3] };
vector_float4 col1 = { matrix.data[4], matrix.data[5], matrix.data[6], matrix.data[7] };
vector_float4 col2 = { matrix.data[8], matrix.data[9], matrix.data[10], matrix.data[11] };
vector_float4 col3 = { matrix.data[12], matrix.data[13], matrix.data[14], matrix.data[15] };
return matrix_from_columns(col0, col1, col2, col3);
}
返回视图控制器
let extrinsic = SCNMatrix4FromMat4(projectionMatrix)
_cameraNode?.camera?.projectionTransform = extrinsic
帧标记姿势
我有一个名为 Framemarker 的对象,它实际上包含标识符和姿势,但该姿势是相同的simd::matrix4x4
作为投影矩阵。
for framemarker in framemarkers {
switch framemarker.identifier {
case 337:
let pose = SCNMatrix4FromMat4(framemarker.pose)
_firstNode?.transform = pose
break
case 357:
let pose = SCNMatrix4FromMat4(framemarker.pose)
_secondNode?.transform = pose
break
default:
break
}
}