问题
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