ARCore расстояние лицо камеры - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь получить расстояние между камерой и центром головы пользователя с помощью AugmentedFace. Это на самом деле хорошо работает, но я могу получить этот результат только один раз, даже если мои вычисления установлены в методе onUpdate. Я где-то что-то упустил, но не понимаю почему.

Вот код.

public class HelloSceneformActivity extends AppCompatActivity implements  Scene.OnUpdateListener{
  private static final String TAG = HelloSceneformActivity.class.getSimpleName();
  private static final double MIN_OPENGL_VERSION = 3.0;
  private HashMap<AugmentedFace, AugmentedFaceNode> faceNodeMap = new HashMap<>();
  private FaceArFragment arFragment;
  private ModelRenderable faceRegionsRenderable;
  private Texture faceMeshTexture;
  private Pose centerFace;
  private TextView tv;
  private float distance;
  private ArSceneView sceneView;
  private Scene scene;
  private Session session;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    if (!checkIsSupportedDeviceOrFinish(this)) {
      return;
    }

    setContentView(R.layout.activity_ux);
      tv = findViewById(R.id.tv);
    arFragment = (FaceArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);

      ModelRenderable.builder()
              .setSource(this, R.raw.fox_face)
              .build()
              .thenAccept(
                      modelRenderable -> {
                          faceRegionsRenderable = modelRenderable;
                          modelRenderable.setShadowCaster(false);
                          modelRenderable.setShadowReceiver(false);
                      });
      Texture.builder()
              .setSource(this,R.drawable.fox_face_mesh_texture)
              .build()
              .thenAccept(texture -> faceMeshTexture = texture);

      sceneView = arFragment.getArSceneView();

        // This is important to make sure that the camera stream renders first so that
        // the face mesh occlusion works correctly.
      sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);

      scene = sceneView.getScene();
      scene.addOnUpdateListener(
              this::onUpdate);
  }


  public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
    if (Build.VERSION.SDK_INT < VERSION_CODES.N) {
      Log.e(TAG, "Sceneform requires Android N or later");
      Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show();
      activity.finish();
      return false;
    }
    String openGlVersionString =
        ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))
            .getDeviceConfigurationInfo()
            .getGlEsVersion();
    if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
      Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later");
      Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG)
          .show();
      activity.finish();
      return false;
    }
    return true;
  }

  @Override
  public void onUpdate(FrameTime frameTime){
      Frame frame = arFragment.getArSceneView().getArFrame();

      Pose cameraPose = frame.getCamera().getPose();
      Log.d("test",String.valueOf(cameraPose));

      if (faceRegionsRenderable == null || faceMeshTexture == null) {
              return;
      }

      Collection<AugmentedFace> faceList =
                  sceneView.getSession().getAllTrackables(AugmentedFace.class);

          // Make new AugmentedFaceNodes for any new faces.
          for (AugmentedFace face : faceList) {
              if (!faceNodeMap.containsKey(face)) {
                  AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
                  faceNode.setParent(scene);
                  faceNode.setFaceRegionsRenderable(faceRegionsRenderable);
                  centerFace = face.getCenterPose();
                  faceNodeMap.put(face, faceNode);
                  faceNode.setFaceMeshTexture(faceMeshTexture);

              }
          }

          // Remove any AugmentedFaceNodes associated with an AugmentedFace that stopped tracking.
          Iterator<Map.Entry<AugmentedFace, AugmentedFaceNode>> iter =
                  faceNodeMap.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry<AugmentedFace, AugmentedFaceNode> entry = iter.next();
              AugmentedFace face = entry.getKey();
              if (face.getTrackingState() == TrackingState.STOPPED) {
                  AugmentedFaceNode faceNode = entry.getValue();
                  faceNode.setParent(null);
                  iter.remove();
              }
          }
          if(centerFace != null) {
              Pose objectPose = centerFace;

              float dx = objectPose.tx() - cameraPose.tx();
              float dy = objectPose.ty() - cameraPose.ty();
              float dz = objectPose.tz() - cameraPose.tz();

              ///Compute the straight-line distance.
              float distance = (float) Math.sqrt(dx * dx + dy * dy + dz * dz);

              Log.d("test", String.valueOf(distance));
          }
      }
  }

Я начал с примера googles do c. Если кто-то более знаком с этой технологией на android, я был бы признателен за любые советы. Большое спасибо!

...