Reputation: 213
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?
Upvotes: 8
Views: 4955
Reputation: 25471
In addition to the other approaches outlined in the other answers, you can also check the hitTestResult to see if it includes a node (this is Kotlin but same approaches holds for Java too):
if (hitTestResult.getNode() != null) {
//We have hit an AR node
Log.d(TAG, "hitTestResult.getNode() != null: " + hitTestResult.getNode());
var hitNode: Node? = hitTestResult.node
//You can add additional checks to see if it is a particuar type if renderable for example
if (hitNode?.renderable == yourRenderable1) {
//Do whatever you want if this renderable type is hit
}
} else {
//We have not hit an ARNode - add your
//code here for this case....
}
Upvotes: 0
Reputation: 58043
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;
}
Upvotes: 3
Reputation: 11
You can just add a listener to the node where your object was added.
node.setOnTapListener((v, event) -> {
showMessage("tap happened");
});
Upvotes: 1
Reputation: 43
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
Upvotes: 3