首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将OpenGLES modelView转换为CATransform3D?

如何将OpenGLES modelView转换为CATransform3D?
EN

Stack Overflow用户
提问于 2013-02-19 00:59:23
回答 1查看 1.4K关注 0票数 17

我的目标是使用图像跟踪和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应用于覆盖视图的层,并将覆盖视图设置为EAGLView的子视图。

我的问题是,正如代码示例中的注释所透露的那样,使用这个sizeFudge因素。除了这个因素,我的代码做了同样的事情as this answer;但这是把我的观点放在错误的地方。

根据经验,我发现如果我不包括sizeFudge术语,那么我的覆盖视图可以很好地跟踪被跟踪对象的方向和平移,但在iPad屏幕上向下和向右偏移-这是一个翻译差异,因此更改用于的术语是有意义的。我首先认为问题出在Vuforia的Target Manager中指定的对象大小。事实证明并非如此;如果我创建了一个十倍大小的目标,那么覆盖视图将绘制在相同的错误位置,但要小十倍(因为AR假设它跟踪的对象更远,我想)。

它只是在这里翻译姿势,让我到达我想要的地方,但这是不令人满意的,因为它对我来说没有任何意义。谁能解释一下从Vuforia提供的OpenGL坐标转换成不依赖于魔术数字的CATransform3D的正确方法?

** more data **

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

这是一张图表,通过将iPad移动到离目标一定距离(位于黑色正方形上方),并用钢笔标记视图中心出现的位置。正方形上方和左侧的点具有如上所述的平移模糊,下方和右侧的点具有sizeFudge==0。希望这里显示的距离和偏移量之间的关系能为比我更了解3D图形的人提供线索,让他们知道转换的问题是什么。

EN

回答 1

Stack Overflow用户

发布于 2013-03-18 18:40:52

这可能首先与视图的设置有关。奇怪的偏移量可能是由于宽度和高度方向错误或任何其他可能的不正确值造成的,比如在iPad上使用iPhone屏幕比例。

你的应用是一种景观吗?如果是这样的话,就让它进入肖像吧。我在过去注意到,应用程序似乎总是以纵向屏幕尺寸启动(我还没有证实这一点),所以如果你的视图设置发生在屏幕是正确的方式之前,你会得到一个不匹配的结果。

你也可以试着计算出它到底减少了多少。而不是像黑客一样乘以size.data :添加另一个翻译并调整数字,直到正确为止。这些数字可能会让你更好地了解正在发生的事情。*10可能只是一个纯粹的偶然,并没有什么意义。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14941435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档