I am working with ARCore in Android Studio using java and trying to implement ray intersection with an object. I started with the Google example we provided (like here: https://developers.google.com/ar/develop/java/getting-started ). When you touch the screen, the beam is projected, and when this beam touches the plane, a snap to the plane (with an anchor / pose) is created at the intersection point.
Then I would like to place a 3D triangle in the world attached to this Pose. I am currently creating my Triangle based on a Pose translation, for example:
In HelloArActivity, during onDrawFrame (...)
//Code from sample, determining the hits on planes MotionEvent tap = mQueuedSingleTaps.poll(); if (tap != null && frame.getTrackingState() == TrackingState.TRACKING) { for (HitResult hit : frame.hitTest(tap)) { // Check if any plane was hit, and if it was hit inside the plane polygon. if (hit instanceof PlaneHitResult && ((PlaneHitResult) hit).isHitInPolygon()) { mTouches.add(new PlaneAttachment( ((PlaneHitResult) hit).getPlane(), mSession.addAnchor(hit.getHitPose()))); //creating a triangle in the world Pose hitPose = hit.getHitPose(); float[] poseCoords = new float[3]; hitPose.getTranslation(poseCoords, 0); mTriangle = new Triangle(poseCoords); } } }
Note. I know that the coordinates of the triangle must be updated every time the coordinates of the Pose are updated. I left this since it is not part of my problem.
Triangular class
public class Triangle { public float[] v0; public float[] v1; public float[] v2;
After that, clicking on the screen again, I create a beam projected from the worked out (x, y) part of the screen using Ian M, its sample code provided in answer to this question: how to check the intersection of the beam with an object in ARCore
Creating Ray in HelloArActivity
float[] screenPointToWorldRay(float xPx, float yPx, Frame frame) { float[] points = new float[12];
The result of this is that no matter where I click on the screen, it is always considered a hit (no matter what distance I add between the points in the triangle constructor).
I suspect this is due to the way the Pose is in the world, and using the Pose translation coordinates as a control point for my triangle is not the way, so I'm looking for the right way to do this, but any comments on other parts of my method are welcome!
I also tested my method for intersecting rays and triangles, and I don't think this is a problem, but I will include it here for completeness:
public Point3f intersectRayTriangle(CustomRay R, Triangle T) { Point3f I = new Point3f(); Vector3f u, v, n; Vector3f dir, w0, w; float r, a, b; u = new Vector3f(T.V1); u.sub(new Point3f(T.V0)); v = new Vector3f(T.V2); v.sub(new Point3f(T.V0)); n = new Vector3f(); // cross product n.cross(u, v); if (n.length() == 0) { return null; } dir = new Vector3f(R.direction); w0 = new Vector3f(R.origin); w0.sub(new Point3f(T.V0)); a = -(new Vector3f(n).dot(w0)); b = new Vector3f(n).dot(dir); if ((float)Math.abs(b) < SMALL_NUM) { return null; } r = a / b; if (r < 0.0) { return null; } I = new Point3f(R.origin); Ix += r * dir.x; Iy += r * dir.y; Iz += r * dir.z; return I; }
Thanks in advance!