Java源码示例:com.google.ar.core.HitResult

示例1
@JavascriptInterface
public void requestHitTest(final String requestId, final float screenX, final float screenY) {
    if (requestId == null) {
        return;
    }

    mSurfaceView.queueEvent(new Runnable() {
        @Override
        public void run() {
            final float hitTestX = screenX * mWebView.getWidth();
            final float hitTestY = screenY * mWebView.getHeight();

            List<HitResult> hitTestResults = null;
            try {
                hitTestResults = mSession.update().hitTest(hitTestX, hitTestY);
            } catch (CameraNotAvailableException e) {
                e.printStackTrace();
            }

            final String scriptString;

            if (hitTestResults.size() > 0) {
                hitTestResults.get(0).getHitPose().toMatrix(mHitTestResultPose, 0);
                scriptString = "ARCoreBridge.hitTestResponse('" + requestId + "', '" + serializeArray(mHitTestResultPose) + "');";

            } else {
                scriptString = "ARCoreBridge.hitTestResponse('" + requestId + "', null);";
            }

            evaluateWebViewJavascript(scriptString);
        }
    });
}
 
示例2
private void handleTap(Frame frame, Camera camera) {
  MotionEvent tap = tapHelper.poll();
  if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
    for (HitResult hit : frame.hitTest(tap)) {
      // Check if any plane was hit, and if it was hit inside the plane polygon
      Trackable trackable = hit.getTrackable();
      // Creates an anchor if a plane or an oriented point was hit.
      if ((trackable instanceof Plane
              && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())
              && (PlaneRenderer.calculateDistanceToPlane(hit.getHitPose(), camera.getPose()) > 0))
          || (trackable instanceof Point
              && ((Point) trackable).getOrientationMode()
                  == OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
        // Hits are sorted by depth. Consider only closest hit on a plane or oriented point.
        // Cap the number of objects created. This avoids overloading both the
        // rendering system and ARCore.
        if (anchors.size() >= 20) {
          anchors.get(0).detach();
          anchors.remove(0);
        }

        // Adding an Anchor tells ARCore that it should track this position in
        // space. This anchor is created on the Plane to place the 3D model
        // in the correct position relative both to the world and to the plane.
        anchors.add(hit.createAnchor());
        break;
      }
    }
  }
}
 
示例3
private void addObject(Uri parse) {
    Frame frame = arFragment.getArSceneView().getArFrame();
    Point point = getScreenCenter();
    if (frame != null) {
        List<HitResult> hits = frame.hitTest((float) point.x, (float) point.y);

        for (int i = 0; i < hits.size(); i++) {
            Trackable trackable = hits.get(i).getTrackable();
            if (trackable instanceof Plane && ((Plane) trackable).isPoseInPolygon(hits.get(i).getHitPose())) {
                placeObject(arFragment, hits.get(i).createAnchor(), parse);
            }
        }
    }
}
 
示例4
@Override
public void onDrawFrame(GL10 gl) {
    // Clear screen to notify driver it should not load any pixels from previous frame.
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    if (session == null) {
        return;
    }
    // Notify ARCore session that the view size changed so that the perspective matrix and
    // the video background can be properly adjusted.
    displayRotationHelper.updateSessionIfNeeded(session);

    try {
        session.setCameraTextureName(backgroundRenderer.getTextureId());

        // Obtain the current frame from ARSession. When the configuration is set to
        // UpdateMode.BLOCKING (it is by default), this will throttle the rendering to the
        // camera framerate.
        Frame frame = session.update();
        Camera camera = frame.getCamera();

        // Handle taps. Handling only one tap per frame, as taps are usually low frequency
        // compared to frame rate.

        MotionEvent tap = queuedSingleTaps.poll();
        if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
            for (HitResult hit : frame.hitTest(tap)) {
                // Check if any plane was hit, and if it was hit inside the plane polygon
                Trackable trackable = hit.getTrackable();
                // Creates an anchor if a plane or an oriented point was hit.
                if ((trackable instanceof Plane && ((Plane) trackable).isPoseInPolygon(hit.getHitPose()))
                    || (trackable instanceof Point
                    && ((Point) trackable).getOrientationMode()
                    == Point.OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
                    // Hits are sorted by depth. Consider only closest hit on a plane or oriented point.
                    // Cap the number of objects created. This avoids overloading both the
                    // rendering system and ARCore.
                    if (anchors.size() >= 20) {
                        anchors.get(0).detach();
                        anchors.remove(0);
                    }
                    // Adding an Anchor tells ARCore that it should track this position in
                    // space. This anchor is created on the Plane to place the 3D model
                    // in the correct position relative both to the world and to the plane.
                    anchors.add(hit.createAnchor());
                    break;
                }
            }
        }


        // Draw background, which is the what the camera is actually capturing.
        backgroundRenderer.draw(frame);

        // Check if we detected at least one plane. If so, hide the loading message.
        if (messageSnackbar != null) {
            for (Plane plane : session.getAllTrackables(Plane.class)) {
                if (plane.getType() == com.google.ar.core.Plane.Type.HORIZONTAL_UPWARD_FACING
                    && plane.getTrackingState() == TrackingState.TRACKING) {
                    hideLoadingMessage();
                    break;
                }
            }
        }


        // If not tracking, don't draw 3d objects.
        if (camera.getTrackingState() == TrackingState.PAUSED) {
            return;
        }
        // Get projection matrix.
        float[] projmtx = new float[16];
        camera.getProjectionMatrix(projmtx, 0, 0.1f, 100.0f);

        // Get camera matrix and draw.
        float[] viewmtx = new float[16];
        camera.getViewMatrix(viewmtx, 0);

        // Visualize anchors created by touch.
        // ie get the anchors from taps and now draw a cube for each place.
        float scaleFactor = 1.0f;
        for (Anchor anchor : anchors) {
            if (anchor.getTrackingState() != TrackingState.TRACKING) {
                continue;
            }
            // Get the current pose of an Anchor in world space. The Anchor pose is updated
            // during calls to session.update() as ARCore refines its estimate of the world.
            anchor.getPose().toMatrix(anchorMatrix, 0);

            // Update and draw the model and its shadow.
            mCube.updateModelMatrix(anchorMatrix, scaleFactor);
            mCube.draw(viewmtx, projmtx);
        }

    } catch (Throwable t) {
        // Avoid crashing the application due to unhandled exceptions.
        Log.e(TAG, "Exception on the OpenGL thread", t);
    }
}
 
示例5
/**
 * Setup the Ar View to use ArCore and tracking. Also add a touch listener to the scene view which checks for single
 * taps on a plane, as identified by ArCore. On tap, set the initial transformation matrix and load the scene.
 */
private void setupArView() {

  mArView = findViewById(R.id.arView);
  mArView.registerLifecycle(getLifecycle());

  // show simple instructions to the user. Refer to the README for more details
  Toast.makeText(this, R.string.camera_instruction_message, Toast.LENGTH_LONG).show();

  mArView.getSceneView().setOnTouchListener(new DefaultSceneViewOnTouchListener(mArView.getSceneView()) {
    @Override
    public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
      // get the hit results for the tap
      List<HitResult> hitResults = mArView.getArSceneView().getArFrame().hitTest(motionEvent);
      // check if the tapped point is recognized as a plane by ArCore
      if (!hitResults.isEmpty() && hitResults.get(0).getTrackable() instanceof Plane) {
        // get a reference to the tapped plane
        Plane plane = (Plane) hitResults.get(0).getTrackable();
        Toast.makeText(MainActivity.this, "Plane detected with a width of: " + plane.getExtentX(), Toast.LENGTH_SHORT)
            .show();
        // get the tapped point as a graphics point
        android.graphics.Point screenPoint = new android.graphics.Point(Math.round(motionEvent.getX()),
            Math.round(motionEvent.getY()));
        // if initial transformation set correctly
        if (mArView.setInitialTransformationMatrix(screenPoint)) {
          // the scene hasn't been configured
          if (!mHasConfiguredScene) {
            loadSceneFromPackage(plane);
          } else if (mArView.getSceneView().getScene() != null) {
            // use information from the scene to determine the origin camera and translation factor
            updateTranslationFactorAndOriginCamera(mArView.getSceneView().getScene(), plane);
          }
        }
      } else {
        Toast.makeText(MainActivity.this, getString(R.string.not_plane_error), Toast.LENGTH_SHORT).show();
        Log.e(TAG, getString(R.string.not_plane_error));
      }
      return super.onSingleTapConfirmed(motionEvent);
    }

    // disable pinch zooming
    @Override public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
      return true;
    }
  });
}