Перемещает ли сборщик 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, спрайт действительно перемещался, как и ожидалось. Это центр вращения, который меня озадачивает.