使用ARCore

时间:2017-09-11 19:24:51

标签: java android augmented-reality arcore

我正在尝试理解Google's ARCore API并推送他们的sample project (java_arcore_hello_ar) to GitHub

在此示例中,当您将应用部署到Android时,会检测到任何水平曲面/平面。如果您点击检测到的平面,“Andy”将会在您点击的位置渲染Andrid机器人。很酷。

我正试图找到代码中的位置:

  1. 检测到水平表面/平面;和
  2. 逻辑在哪里调整大小&正确地重新定位安迪(我假设如果你点击的点远离相机,他会变小,等等。)
  3. 相信当检测到飞机时,Android框架会调用onSurfaceCreated方法:

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    
        // Create the texture and pass it to ARCore session to be filled during update().
        mBackgroundRenderer.createOnGlThread(/*context=*/this);
        mSession.setCameraTextureName(mBackgroundRenderer.getTextureId());
    
        // Prepare the other rendering objects.
        try {
            mVirtualObject.createOnGlThread(/*context=*/this, "andy.obj", "andy.png");
            mVirtualObject.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);
    
            mVirtualObjectShadow.createOnGlThread(/*context=*/this,
                "andy_shadow.obj", "andy_shadow.png");
            mVirtualObjectShadow.setBlendMode(BlendMode.Shadow);
            mVirtualObjectShadow.setMaterialProperties(1.0f, 0.0f, 0.0f, 1.0f);
        } catch (IOException e) {
            Log.e(TAG, "Failed to read obj file");
        }
        try {
            mPlaneRenderer.createOnGlThread(/*context=*/this, "trigrid.png");
        } catch (IOException e) {
            Log.e(TAG, "Failed to read plane texture");
        }
        mPointCloud.createOnGlThread(/*context=*/this);
    }
    

    然而,代码看起来像它假定用户已经在表面上轻敲。我没有看到if - 条件基本上说“渲染Andy 如果用户已经点击了检测到的平面/表面。”。任何人都可以发现这可能发生的地方吗?

1 个答案:

答案 0 :(得分:4)

点击检测由mGestureDetector

完成
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        onSingleTap(e);
        return true;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }
});

哪个链接到SurfaceView

mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }
});

这两件事都发生在onCreate(),所以现在每次点击表面视图(活动中的“主要”视图),

private void onSingleTap(MotionEvent e) {
    // Queue tap if there is space. Tap is lost if queue is full.
    mQueuedSingleTaps.offer(e);
}
调用

并存储点击。然后在每个框架图中处理该队列(这又由系统的UI绘图周期发出)here

MotionEvent tap = mQueuedSingleTaps.poll();
if (tap != null && frame.getTrackingState() == TrackingState.TRACKING) {
    for (HitResult hit : frame.hitTest(tap)) {
       ...

这会添加一个新锚点(即在物理世界中“锁定”的点“),在该锚点上呈现Android对象(cf. this line)