Проблемы с вращением ARCore ModelRenderable с использованием Node.setLookDirection - PullRequest
0 голосов
/ 19 июня 2019

Перемещает ли сборщик ARCore ModelRenderable локальное происхождение загружаемых моделей OBJ?

В ARCore у меня есть спрайт, который я хотел бы повернуть, чтобы он всегда был лицом к камере. Я использую ModelRenderable для загрузки файла OBJ. Я присоединяю ModelRenderable к Узлу, который прикреплен к Якору в мире. Все загружается и отображается нормально, за исключением того, что когда я вызываю Node.setLookDirection (), спрайт вращается вокруг точки в центре своего нижнего края, а не (0,0), вокруг которой определены все его вершины. Я могу перемещать Узел, используя setLocalPosition, но точка вращения всегда находится в центре нижней части спрайта. Это приводит меня к мысли, что проблема связана с modelRenderable, а не с Node.setLookDirection (). Любые комментарии приветствуются.

Вот файл OBJ:

# File: Sprite.obj

mtllib Yel.mtl

#
# object Sprite
#
#   -1,1         1,1
#       v2     v1
#
#           +
#
#       v4     v3
#   -1,-1        1,-1
#

v   0.25  0.25 0.0
v  -0.25  0.25 0.0
v   0.25 -0.25 0.0
v  -0.25 -0.25 0.0
# 4 vertices

# temporary test:
#v   0.25 -1.00 0.0
#v  -0.25 -1.00 0.0
#v   0.25 -1.50 0.0
#v  -0.25 -1.50 0.0

vt 1.0 1.0 0.0
vt 0.0 1.0 0.0
vt 1.0 0.0 0.0
vt 0.0 0.0 0.0
# 4 texture coords

o Sprite
g Sprite
usemtl Yel
f 1/1 2/2 3/3
f 3/3 2/2 4/4
# 2 faces

Вот код для загрузки и поворота (сводка):

ModelRenderable oSprite;
Node oSpriteNode;


protected void onCreate(Bundle savedInstanceState) {
  ArFragment arFragment = (ArFragment)getSupportFragmentManager().findFragmentById(R.id.RENDER_SCRN);
  arFragment.getArSceneView().getScene().addOnUpdateListener(this);
  arFragment.getArSceneView().getScene().addOnUpdateListener(arFragment);

  // Load the sprite model

  ModelRenderable.builder()
                 .setSource(this, Uri.parse("Sprite.sfb"))
                 .build()
                 .thenAccept(renderable -> oSprite = renderable)
                 .exceptionally(throwable -> {
                     Toast toast = Toast.makeText(this, "Unable to load sprite renderable", Toast.LENGTH_LONG);
                     toast.setGravity(Gravity.CENTER, 0, 0);
                     toast.show();
                     return null;
                 });

  // Anchor the sprite in the world

  arFragment.setOnTapArPlaneListener(
    (HitResult hitresult, Plane plane, MotionEvent motionevent) -> {
      Anchor anchor = hitresult.createAnchor();
      AnchorNode anchorNode = new AnchorNode(anchor);
      anchorNode.setParent(arFragment.getArSceneView().getScene());

      oSpriteNode = new Node();
      oSpriteNode.setParent(anchorNode);
      oSpriteNode.setRenderable(oSprite);

//MOVE      Vector3 vSpriteCtr = new Vector3(0, 1, 0);
//MOVE      oCloudOrigin.setLocalPosition(vSpriteCtr);
      Log.i(TAG, "OnTapArPlaneListener: Dropping a new sprite at " + oSpriteNode.getWorldPosition());
    }
  );
}


public void onUpdate(FrameTime oFrameTime) {

  // Update the sprite rotation

  Frame frame = arFragment.getArSceneView().getArFrame();
  Camera cam = frame.getCamera();
  Pose pose = cam.getDisplayOrientedPose();
  float[] afPos = pose.getTranslation();
  Vector3 vEye = new Vector3(afPos[0], afPos[1], afPos[2]);

  Vector3 vSpritePos = new Vector3();
  vSpritePos.x = oSpriteNode.getWorldPosition().x;
  vSpritePos.y = oSpriteNode.getWorldPosition().y;
  vSpritePos.z = oSpriteNode.getWorldPosition().z;

  // Rotate the sprite to face the AR camera.

  Vector3 vLook = Vector3.subtract(vSpritePos, vEye);  // From camera to sprite
  Vector3 vUp = Vector3.up();
  oSpriteNode.setLookDirection(vLook, vUp);
}

Приведенный выше код не будет работать сам по себе, но я считаю, что я включил все, что имеет отношение к делу. Учитывая модель, я ожидаю, что спрайт будет вращаться вокруг своего центра. Вместо этого, как будто источник перемещен в центр нижнего края, и он вращается вокруг своей локальной оси X, как игральная карта, стоящая вертикально в горизонтальной плоскости. Вращение вокруг Y работает как положено. Смещение значений вершин Y в файле OBJ большими числами (см. Закомментированные вершины) вообще не имеет значения.

Я что-то упускаю из виду? Есть ли где-нибудь флаг, который говорит: «Да, я действительно хочу определить, где находится мое собственное происхождение»?

Я еще раз повторю, что когда я перемещал спрайт с помощью setLocalPosition, спрайт действительно перемещался, как и ожидалось. Это центр вращения, который меня озадачивает.

...