我应该如何将OpenGLES modelView转换为CATransform3D?

时间:2013-02-18 16:59:23

标签: ios uikit opengl-es-2.0 augmented-reality vuforia

我的目标是使用图像跟踪和Vuforia AR SDK覆盖标准的UIKit视图(暂时,我只是创建一个UILabel但最终我将拥有自定义内容)。我有一些有用的东西,但有一个我不能解释的“软糖”术语。我想知道我的错误在哪里,所以我可以证明这种修正的存在,或者使用一种已知有效的不同算法。

我的项目基于Vuforia SDK中的ImageTargets示例项目。他们EAGLView迭代结果以呈现OpenGL茶壶的地方,我已经用我的ObjC ++类TrackableObjectController调用了它。对于每个可跟踪的结果,它执行以下操作:

- (void)augmentedRealityView:(EAGLView *)view foundTrackableResult:(const QCAR::TrackableResult *)trackableResult
{
    // find out where the target is in Core Animation space
    const QCAR::ImageTarget* imageTarget = static_cast<const QCAR::ImageTarget*>(&(trackableResult->getTrackable()));
    TrackableObject *trackable = [self trackableForName: TrackableName(imageTarget)];
    trackable.tracked = YES;
    QCAR::Vec2F size = imageTarget->getSize();
    QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackableResult->getPose());
    CGFloat ScreenScale = [[UIScreen mainScreen] scale];
    float xscl = qUtils.viewport.sizeX/ScreenScale/2;
    float yscl = qUtils.viewport.sizeY/ScreenScale/2;
    QCAR::Matrix44F projectedTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
    QCAR::Matrix44F qcarTransform = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
    /* this sizeFudge constant is here to put the label in the correct place in this demo; I had thought that
     * the problem was related to the units used (I defined the length of the target in mm in the Target Manager;
     * the fact that I've got to multiply by ten here could be indicative of the app interpreting length in cm).
     * That turned out not to be the case, when I changed the reported length of the target it stopped drawing the
     * label at the correct size. Currently, therefore, the app and the target database are both using mm, but
     * there's the following empirically-divised fudge factor to get the app to position the correctly-sized view
     * in the correct position relative to the detected object.
     */
    const double sizeFudge = 10.0;
    ShaderUtils::translatePoseMatrix(sizeFudge * size.data[0] / 2, sizeFudge * size.data[1] / 2, 0, projectedTransform.data);
    ShaderUtils::scalePoseMatrix(xscl, -yscl, 1.0, projectedTransform.data); // flip along y axis
    ShaderUtils::multiplyMatrix(projectedTransform.data, qUtils.projectionMatrix.data, qcarTransform.data);
    ShaderUtils::multiplyMatrix(qcarTransform.data, modelViewMatrix.data, qcarTransform.data);
    CATransform3D transform = *((CATransform3D*)qcarTransform.data); // both are array[16] of float
    transform = CATransform3DScale(transform,1,-1,0); //needs flipping to draw
    trackable.transform = transform;
}

然后在主线程上调用其他代码来查看我的TrackableObject个实例,将计算出的CATransform3D应用于覆盖视图的图层,并将覆盖视图设置为{的子视图{1}}。

我的问题是,正如代码示例中的注释已经放弃,使用此EAGLView因子。除了这个因素,我的代码做了同样的事情as this answer;但这让我把观点放在了错误的地方。

根据经验,我发现如果我不包含sizeFudge术语,那么我的叠加视图会很好地跟踪被跟踪对象的方向和平移,但会在iPad屏幕上向下和向右偏移 - 这是一个翻译差异,所以更改用于的术语是有道理的。我首先想到的问题是Vuforia目标管理器中指定的对象大小。结果并非如此;如果我创建了十倍大小的目标,那么叠加视图会在相同的,不正确的位置绘制,但会小十倍(因为AR假设它跟踪的对象距离更远,我想)。

这只是翻译这里的姿势让我想到的地方,但这并不令人满意,因为它对我没有任何意义。任何人都可以解释从Vuforia提供的OpenGL坐标转换为不依赖幻数的CATransform3D的正确方法吗?

** 更多数据 **

问题比我写这个问题时想象的要复杂得多。实际上,标签的位置似乎取决于从iPad到被跟踪物体的距离,尽管不是线性的。还有一个明显的系统错误。

这是通过将iPad移动到远离目标一定距离(位于黑色方块上方)上构建的图表,并使用笔在视图中心出现的位置进行标记。正方形的上方和左侧的点具有如上所述的平移软糖,下方和右侧的点具有sizeFudge。希望这里显示的距离和偏移之间的关系能够让对3D图形有更多了解的人比我更了解变换的问题。

Chart as described in the previous paragraph.

1 个答案:

答案 0 :(得分:1)

这可能与您首先设置视图有关。宽度和高度是错误的方式或任何其他可能的错误值,如在iPad上使用iPhone屏幕比例,可能导致奇怪的偏移。

您的应用是否具有风景?如果是这样的话,那就试试吧。我之前已经注意到,应用程序似乎总是以纵向屏幕尺寸启动(虽然我还没有确认),所以如果您的视图设置在屏幕之前发生,那么“正确的方式”将导致不匹配。< / p>

你也可以尝试确切地知道它的数量。而不是将size.data乘以黑客:添加另一个翻译并调整数字直到它是正确的。这些数字可能会让您更好地了解正在发生的事情。 * 10可能只是纯粹的侥幸,并没有任何意义。