Управление вращением суставов виртуального персонажа с помощью OpenNI + Kinect - PullRequest
0 голосов
/ 22 января 2019

Я запускаю проект, в котором мне нужно управлять виртуальным персонажем.Персонаж отображается в нескольких 3D-движках, таких как Three.JS и iOS SceneKit.

Я получаю кватернионы каждого соединения скелета с OpenNI, и это выглядит примерно так:

Код, который сохраняет и передает кватернион, выглядит следующим образом:

float confidence = context.getJointOrientationSkeleton(userId, jointName, 
joint);
joints[jointIndex]=joint.m00;
joints[jointIndex+1]=joint.m01;
joints[jointIndex+2]=joint.m02;
joints[jointIndex+3]=joint.m10;
joints[jointIndex+4]=joint.m11;
joints[jointIndex+5]=joint.m12;
joints[jointIndex+6]=joint.m20;
joints[jointIndex+7]=joint.m21;
joints[jointIndex+8]=joint.m22;
jointIndex+=9;

Это повторяется для каждого соединения скелета.

Последняя строка и последний столбец всегда [0 0 0 1] [0, 0, 0, 1], поэтому я просто добавляю это на клиенте, как только получу его, и создаю 4x4 matrix.

Я хочу иметь возможность делать правильные повороты с этими данными, но повороты, которые я получаю,определенно неправильно.

Вот как я обрабатываю матрицу: (псевдокод)

row1 = [m00 m01 m02 0]
row2 = [m10 m11 m12 0]
row3 = [m20 m21 m22 0]
row4 = [0 0 0 1]

matrix4by4 = matrix4x4(rows:[row1,row2,row3,row4])

А затем я получил кватернион двумя методами, и оба метода показали плохие вращения, Я не могу найти, что не так или что мне не хватает.

Первый метод

Есть функция iOS, которая получает матрицу 3x3 или 4x4 и преобразует ее в кватернион:

boneRotation = simd_quatf.init(matrix4by4).vector //X,Y,Z,W

Второйметод

Я нашел следующий код в Интернете:

let tr = m00 + m11 + m22

var qw = 0
var qx = 0
var qy = 0
var qz = 0
if (tr > 0) {
    var S = sqrt(tr+1.0) * 2 // S=4*qw
    qw = 0.25 * S
    qx = (m21 - m12) / S
    qy = (m02 - m20) / S
    qz = (m10 - m01) / S
} else if ((m00 > m11) && (m00 > m22)) {
    var S = sqrt(1.0 + m00 - m11 - m22) * 2 // S=4*qx
    qw = (m21 - m12) / S
    qx = 0.25 * S
    qy = (m01 + m10) / S
    qz = (m02 + m20) / S
} else if (m11 > m22) {
    var S = sqrt(1.0 + m11 - m00 - m22) * 2 // S=4*qy
    qw = (m02 - m20) / S
    qx = (m01 + m10) / S
    qy = 0.25 * S
    qz = (m12 + m21) / S
} else {
    let S = sqrt(1.0 + m22 - m00 - m11) * 2 // S=4*qz
    var = (m10 - m01) / S
    qx = (m02 + m20) / S
    qy = (m12 + m21) / S
    qz = 0.25 * S
}

boneRotation = vector4(qx, qy, qw, qz)

Я начал тестирование только с поворотом плеча и локтя, чтобы помочь мне визуализировать, что может быть неправильным или отсутствующим, и сделалвидео.

Вот как оно ведет себя: https://www.youtube.com/watch?v=xUtNiwH_AGk

Чего мне не хватать?Например, оси вращения плеча выглядят так:

Ось X X-Axis

Ось Y Y-Axis

Ось Z Z-Axis

Заранее спасибо: -)

Видео YouTuve: https://www.youtube.com/watch?v=xUtNiwH_AGk YouTube Video

...