Удалить все вращения из якоря в ArCore - PullRequest
0 голосов
/ 30 января 2020

Итак, я создаю приложение, в котором все размещенные пользователем объекты должны быть направлены в одном направлении. Для этого мне нужно удалить все повороты с якоря, на котором находится объект. Это код для чтения позы с якоря и размещения объекта:

 for (ColoredAnchor coloredAnchor : anchors) {
        if (coloredAnchor.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.
        coloredAnchor.anchor.getPose().toMatrix(anchorMatrix, 0);


        // Update and draw the model and its shadow.
        virtualObject.updateModelMatrix(anchorMatrix, scaleFactor / 12f);
        virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba, arrowColor);
}

Как убрать вращение из матрицы, но сохранить локальное положение якоря?

I знаю, что вы можете использовать

coloredAnchor.anchor.getPose().getRotationQuaternion();

для извлечения вращения и

Matrix.rotateM();

для вращения якорной матрицы. Но rotateM принимает угол в градусах в качестве ввода, тогда как getRotationQuaternion() выводит другой формат. Может быть, можно преобразовать вывод кватерниона в градусы и просто повернуть матрицу в обратном направлении?

В целом 3D-модель всегда должна быть ориентирована в одном направлении в реальном мире.

1 Ответ

0 голосов
/ 30 января 2020

Я думаю, что решил это. Я конвертирую значения из кватернионов в углы Эйлера ( Преобразование ). После этого я использую вычисленные повороты в обратном направлении на ar-объекте. Мне нужно провести дополнительное тестирование, но пока оно работает отлично.

 coloredAnchor.anchor.getPose().toMatrix(anchorMatrix, 0);

double w = coloredAnchor.anchor.getPose().qw();
double x = coloredAnchor.anchor.getPose().qx();
double y = coloredAnchor.anchor.getPose().qy();
double z = coloredAnchor.anchor.getPose().qz();

double xAngle = 0;
double yAngle = 0;
double zAngle = 0;

double sinr_cosp = 2 * (w * x + y * z);
double cosr_cosp = 1 - 2 * (x * x + y * y);
xAngle = Math.atan2(sinr_cosp, cosr_cosp);

double sinp = 2 * (w * y - z * x);
if (Math.abs(sinp) >= 1) {
    yAngle = Math.copySign(Math.PI / 2, sinp); // use 90 degrees if out of range
} else {
    yAngle = Math.asin(sinp);
}

double siny_cosp = 2 * (w * z - x * y);
double cosy_cosp = 1 - 2 * (y * y + z * z);

zAngle = Math.atan2(siny_cosp, cosy_cosp);

xAngle = Math.toDegrees(xAngle);
yAngle = Math.toDegrees(yAngle);
zAngle = Math.toDegrees(zAngle);

Matrix.rotateM(anchorMatrix, 0, (float) -xAngle, 1f, 0f, 0f);
Matrix.rotateM(anchorMatrix, 0, (float) -yAngle + DYNAMIC_BUILDING_FIX, 0f, 1f, 0f);
Matrix.rotateM(anchorMatrix, 0, (float) -zAngle, 0f, 0f, 1f);

virtualObject.updateModelMatrix(anchorMatrix, scaleFactor / 12f);
virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba, arrowColor);

Это довольно длинное и хакерское решение, хотя, может быть, у кого-то есть лучшая идея, как его решить.

...