我正在尝试放置一个锚并将其显示在用户点击屏幕的位置,该屏幕返回X和Y坐标。
tapX = tap.getX();
tapY = tap.getY();
我想使用这些信息为我的模型创建一个矩阵。 (即将我的3D模型放在用户点击的位置)
现在我试过了:
float sceneX = (tap.getX()/mSurfaceView.getMeasuredWidth())*2.0f - 1.0f;
float sceneY = (tap.getY()/mSurfaceView.getMeasuredHeight())*-2.0f + 1.0f; //if bottom is at -1. Otherwise same as X
Pose temp = frame.getPose().compose(Pose.makeTranslation(sceneX, sceneY, -1.0f)).extractTranslation();
我现在暂时将3D物体放在前面1米处。我没有得到合适的位置。
有没有办法将局部坐标转换为世界坐标?
答案 0 :(得分:1)
点击屏幕并没有与现实世界进行一对一的映射。它为您提供了无数个可能的(x, y, z)
位置,这些位置位于从相机延伸出来的光线上。例如,如果我点击屏幕的中心,那可能对应于离我一米远的物体,距离地面两米,地板,地板等等。
因此,您需要一些额外的约束来告诉ARCore沿着此光线放置锚点的位置。在示例应用程序中,这是通过将此光线与ARCore检测到的平面相交来完成的。与平面相交的光线描述单个点,因此您需要进行设置。这是他们在示例应用程序中执行此操作的方式:
MotionEvent tap = mQueuedSingleTaps.poll();
if (tap != null && frame.getTrackingState() == TrackingState.TRACKING) {
for (HitResult hit : frame.hitTest(tap)) {
// Check if any plane was hit, and if it was hit inside the plane polygon.
if (hit instanceof PlaneHitResult && ((PlaneHitResult) hit).isHitInPolygon()) {
// Cap the number of objects created. This avoids overloading both the
// rendering system and ARCore.
if (mTouches.size() >= 16) {
mSession.removeAnchors(Arrays.asList(mTouches.get(0).getAnchor()));
mTouches.remove(0);
}
// Adding an Anchor tells ARCore that it should track this position in
// space. This anchor will be used in PlaneAttachment to place the 3d model
// in the correct position relative both to the world and to the plane.
mTouches.add(new PlaneAttachment(
((PlaneHitResult) hit).getPlane(),
mSession.addAnchor(hit.getHitPose())));
// Hits are sorted by depth. Consider only closest hit on a plane.
break;
}
}
}
特别针对您的情况,我会看一下the rendering code的AR绘图应用。它们的函数GetWorldCoords()
从屏幕坐标到世界坐标,假设与屏幕有一定距离。