Я пытаюсь добавить перемещение объектов с помощью прокрутки одним пальцем. (См., Например, стикеры Google AR). Я использую собственный ARCore / OpenGL, изначально основанный на примерах ARCore. Когда вы перемещаете 1 палец, я хочу переместить объект в трехмерном пространстве по осям X и Z.
Я могу легко создать движение с помощью Translation, однако он выполняет движение на основе исходной ориентации камеры. Если вы физически переместите телефон / камеру на несколько шагов в сторону, движения пальцев больше не будут соответствовать тому, что ожидал бы пользователь.
Поэтому я изменил свой код и сопоставил расстояния пальца X и DistanceY, которые перемещаются, чтобы повлиять на координаты X и Z в зависимости от угла изменения от исходной начальной точки камеры до текущей точки камеры.
Проблема, с которой я сталкиваюсь, - это определение угла, на который была перемещена камера. Я смотрел значение из матрицы обзора камеры:
camera.getViewMatrix(viewmtx, 0);
Но координаты X, Y и Z всегда равны нулю. Я предполагаю, что это потому, что камера всегда является исходной точкой? Кто-нибудь знает, как вычислить угол поворота камеры от 3D-объекта с помощью библиотек ARCore / OpenGL ES? Красный угол на иллюстрации ниже (с точки зрения сверху вниз) - это то, что я пытаюсь получить. Извините за грубый рисунок:
Вот мой код для справки:
// Handle Gestures - Single touch for Translation and Placement
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener()
{
@Override
public boolean onSingleTapUp(MotionEvent e)
{
onSingleTap(e);
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
if (e2.getPointerCount() == 1 && ...)
{
double angle = findCameraAngleFromOrigin();
double speed = 0.005d;
if (angle / 90d < 1) //Quadrant 1
{
double transX = -(distanceY * (angle / 90d)) + (distanceX * ((90d - angle) / 90d));
double transY = (distanceY * ((90d - angle) / 90d)) + (distanceX * (angle / 90d));
mTranslationX.set(mTranslationX.size() - 1, (float) (mTranslationX.get(mTranslationX.size() - 1) + (transX * -speed)));
mTranslationZ.set(mTranslationZ.size() - 1, (float) (mTranslationZ.get(mTranslationZ.size() - 1) + (transY * -speed)));
}
else if (angle / 90d < 2) //Quadrant 2
{
angle -= 90d;
double transX = (distanceX * (angle / 90d)) + (distanceY * ((90d - angle) / 90d));
double transY = (-distanceX * ((90d - angle) / 90d)) + (distanceY * (angle / 90d));
mTranslationX.set(mTranslationX.size() - 1, (float) (mTranslationX.get(mTranslationX.size() - 1) + (transX * speed)));
mTranslationZ.set(mTranslationZ.size() - 1, (float) (mTranslationZ.get(mTranslationZ.size() - 1) + (transY * speed)));
}
else if (angle / 90d < 3) //Quadrant 3
{
angle -= 180d;
double transX = (distanceY * (angle / 90d)) + (-distanceX * ((90d - angle) / 90d));
double transY = (-distanceY * ((90d - angle) / 90d)) + (-distanceX * (angle / 90d));
mTranslationX.set(mTranslationX.size() - 1, (float) (mTranslationX.get(mTranslationX.size() - 1) + (transX * -speed)));
mTranslationZ.set(mTranslationZ.size() - 1, (float) (mTranslationZ.get(mTranslationZ.size() - 1) + (transY * -speed)));
}
else //Quadrant 4
{
angle -= 270d;
double transX = (-distanceX * (angle / 90d)) + (-distanceY * ((90d - angle) / 90d));
double transY = (distanceX * ((90d - angle) / 90d)) + (-distanceY * (angle / 90d));
mTranslationX.set(mTranslationX.size() - 1, (float) (mTranslationX.get(mTranslationX.size() - 1) + (transX * speed)));
mTranslationZ.set(mTranslationZ.size() - 1, (float) (mTranslationZ.get(mTranslationZ.size() - 1) + (transY * speed)));
}
return true;
}
return false;
}
}
РЕДАКТИРОВАТЬ: обновить код