没有平面的

时间:2017-10-04 14:19:13

标签: java arcore

我是这个ARCore的新手,我一直在关注SDK中提供的HelloAR Java Android Studio项目。

Everthing工作正常并且非常酷,但是,即使没有检测到飞机,我也想在触摸屏幕时放置/放下物体。让我解释一下......

据我所知,它将检测水平平面,并且只在那些水平平面上,我可以放置3D物体进行运动追踪。

有没有办法(可能使用PointCloud信息)能够在场景中放置一个物体,即使没有检测到水平面?有点像这些例子吗? https://experiments.withgoogle.com/ar/flight-paths https://experiments.withgoogle.com/ar/arcore-drawing

我知道他们正在使用Unity和openFrameworks,但这可以用Java完成吗?

另外,我看过了 How to put an object in the air?how to check ray intersection with object in ARCore

但我不认为我理解了Ancor的概念(我设法将对象放在场景中,但它要么立即消失,要么只是一个普通的OpenGL对象,不知道现实世界。

我想要了解的是: - 如何以及是否可以创建自定义/用户定义的平面,即ARCore不会自动检测到的平面? - 我怎样才能创建一个Ancor(我想这个样本在PlaneAttachment类中完成),它没有链接到任何连接到某个PointCloud点的平面OR? - 如何绘制对象并将其放在先前创建的Ancor上?

我认为这个问题太多了,但是查看API文档根本没有帮助我

谢谢!

修改

这是我添加到HelloArActivity.java的代码(除了// *****之前和之前的行之外,Everything与原始文件相同...

@Override
public void onDrawFrame(GL10 gl) {
...
        MotionEvent tap = mQueuedSingleTaps.poll();

        // I added this to use screenPointToWorldRay function in the second link I posted... I am probably using this wrong
        float[] worldXY = new float[6];
...
        if (tap != null && frame.getTrackingState() == TrackingState.TRACKING) {

            // ***** I added this to use screenPointToWorldRay function
            worldXY = screenPointToWorldRay(tap.getX(), tap.getY(), frame);
...

        }
...

        // Visualize anchors created by touch.
        float scaleFactor = 1.0f;
        for (PlaneAttachment planeAttachment : mTouches) {
...
        }

        // ***** This places the object momentarily in the scene (it disappears immediately)  
        frame.getPose().compose(Pose.makeTranslation(worldXY[3], worldXY[4], worldXY[5])).toMatrix(mAnchorMatrix, 0);

        // ***** This places the object in the middle of the scene but since it is not attached to anything, there is no tracking, it is always in the middle of the screen (pretty much expected behaviour)
        // frame.getPose().compose(Pose.makeTranslation(0, 0, -1.0f)).toMatrix(mAnchorMatrix, 0);

        // *****I duplicated this code which gets executed ONLY when touching a detected plane/surface.
        mVirtualObject.updateModelMatrix(mAnchorMatrix, scaleFactor);
        mVirtualObjectShadow.updateModelMatrix(mAnchorMatrix, scaleFactor);
        mVirtualObject.draw(viewmtx, projmtx, lightIntensity);
        mVirtualObjectShadow.draw(viewmtx, projmtx, lightIntensity);
...
}

1 个答案:

答案 0 :(得分:0)

您首先必须通过Frame.hitTest执行一次命中测试,并遍历HitResult对象,直到命中了Point类型的Trackable。然后,您可以通过HitResult.getHitPose为该命中结果检索一个姿势,或将锚点附加到该点,并通过ArAnchor.getPose从该姿势得到姿势(最佳方法)。

但是,如果您想从ArPointCloud.getPoints检索的仲裁点自己进行此操作,则将需要更多的工作。通过这种方法,问题可以有效地简化为“如何从一个点导出姿态/坐标基础?”。

在平面上工作时,导出姿势相对容易,因为您可以将平面法线用作模型的上(y)向量,并且可以选择x和y向量来配置希望模型“面对”的位置关于那架飞机。 (其中每个向量都垂直于其他向量)

enter image description here

当试图从一个点导出基础时,必须选择相对于您的原点的所有三个向量(x,y和z)。您可以使用ArCamera.getViewMatrix通过相机视图矩阵转换矢量(0,1,0)(假设您希望模型的顶部面对屏幕的顶部)来导出向上矢量。然后,您可以选择x和z向量作为将模型朝向所需方向的任意两个相互垂直的向量。