Detecting if an tap event with ARCore hits an already added 3d object

霸气de小男生 提交于 2019-12-21 13:11:09

问题


I am following the ARCore sample (https://github.com/google-ar/arcore-android-sdk) and I am trying to remove object 3d (andy) already added. How can I detect if an tap event with ARCore hits an already added 3d object?


回答1:


Using a listener is quite common approach in such situation:

private Node getModel() {
    Node node = new Node();
    node.setRenderable(modelRenderable);
    Context cont = this;
    node.setOnTapListener((v, event) -> {
        Toast.makeText(
            cont, "Model was touched", Toast.LENGTH_LONG)   // Toast Notification 
            .show();
    });
    return node;
}



回答2:


I had the same question these days, I tried 2 solutions,

1. frame.hitTest(MotionEvent)

2. project the vertex from arcore world to 2d coordinate in view

At first I use 1. to get the hit pose on plane and compare to the pose of already existed 3d object, but once the 3d object left the plane this will not work.

In the end I use 2. to get the vertex of the 3d object on view, then do a hit test with the tap position.

If you are following the ARCore sample, you can see this line in the draw method of ObjectRenderer.java

Matrix.multiplyMM(mModelViewProjectionMatrix, 0, 
                  cameraPerspective, 0, mModelViewMatrix, 0);

"mModelViewProjectionMatrix" just use this ModelViewProjection matrix to mapping the vertex of your already added 3d object from 3d arcore world to 2d view.

In my case, I do something like this,

pose.toMatrix(mAnchorMatrix, 0);
objectRenderer.updateModelMatrix(mAnchorMatrix, 1);
objectRenderer.draw(cameraView, cameraPerspective, lightIntensity);

float[] centerVertexOf3dObject = {0f, 0f, 0f, 1};
float[] vertexResult = new float[4];
Matrix.multiplyMV(vertexResult, 0, 
                  objectRenderer.getModelViewProjectionMatrix(), 0, 
                  centerVertexOf3dObject, 0);
// circle hit test
float radius = (viewWidth / 2) * (cubeHitAreaRadius/vertexResult[3]);
float dx = event.getX() - (viewWidth / 2) * (1 + vertexResult[0]/vertexResult[3]);
float dy = event.getY() - (viewHeight / 2) * (1 - vertexResult[1]/vertexResult[3]);
double distance = Math.sqrt(dx * dx + dy * dy);
boolean isHit = distance < radius;

I use this in ARCore Measure app,
https://play.google.com/store/apps/details?id=com.hl3hl3.arcoremeasure

and the source code, https://github.com/hl3hl3/ARCoreMeasure/blob/master/app/src/main/java/com/hl3hl3/arcoremeasure/ArMeasureActivity.java




回答3:


You can just add a listener to the node where your object was added.

    node.setOnTapListener((v, event) -> {
        showMessage("tap happened");
    });


来源:https://stackoverflow.com/questions/46728036/detecting-if-an-tap-event-with-arcore-hits-an-already-added-3d-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!