【发布时间】:2018-03-25 11:29:51
【问题描述】:
我正在关注 ARCore 示例 (https://github.com/google-ar/arcore-android-sdk),我正在尝试删除已添加的对象 3d (andy)。 如何检测带有 ARCore 的点击事件是否击中了已添加的 3d 对象?
【问题讨论】:
标签: java android augmented-reality arcore
我正在关注 ARCore 示例 (https://github.com/google-ar/arcore-android-sdk),我正在尝试删除已添加的对象 3d (andy)。 如何检测带有 ARCore 的点击事件是否击中了已添加的 3d 对象?
【问题讨论】:
标签: java android augmented-reality arcore
在这种情况下使用listener 是很常见的方法:
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 个解决方案,
1. frame.hitTest(MotionEvent)
2.将顶点从arcore世界投影到视图中的二维坐标
一开始我使用1.来获取平面上的命中姿势并与已经存在的3d物体的姿势进行比较,但是一旦3d物体离开平面,这将不起作用。
最后我使用 2. 来获取视图中 3d 对象的顶点,然后使用点击位置进行命中测试。
如果你正在关注 ARCore 示例,你可以在 ObjectRenderer.java 的 draw 方法中看到这一行
Matrix.multiplyMM(mModelViewProjectionMatrix, 0,
cameraPerspective, 0, mModelViewMatrix, 0);
“mModelViewProjectionMatrix”只需使用此 ModelViewProjection 矩阵将您已添加的 3d 对象的顶点从 3d arccore 世界映射到 2d 视图。
就我而言,我会做这样的事情,
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;
我在 ARCore Measure 应用中使用它,
https://play.google.com/store/apps/details?id=com.hl3hl3.arcoremeasure
【讨论】:
您可以在添加对象的节点上添加一个侦听器。
node.setOnTapListener((v, event) -> {
showMessage("tap happened");
});
【讨论】:
除了其他答案中列出的其他方法之外,您还可以检查 hitTestResult 以查看它是否包含节点(这是 Kotlin,但同样的方法也适用于 Java):
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....
}
【讨论】: