Разбираемся в кватернионе сенсоров Android TYPE_GAME_ROTATION_VECTOR

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

Вот пример того, чего я пытаюсь достичь:

https://thewikihow.com/video_9lq_5B-vNGE

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

В Unity, когда я использую кватернион для поворота 3D-объекта, оси не совпадают. Например, когда я поворачиваю телефон по оси Y, он поворачивает трехмерный объект по оси X. Я попытался переназначить оси на правильные, но мне это не удалось.

Это была одна из моих попыток, когда я пытаюсь преобразовать кватернион в углы Эйлера, настроить X, Y и Z вручную и преобразовать его обратно в кватернионы. В результате получается все более беспорядочное вращение, которое для меня не имеет смысла.

//This is where I create a quaterion out of the values I get from the android phone
Quaternion myQuaternion = new Quaternion(pos.x, pos.y, pos.z, pos.w);

//This is where I transform the quaterions to Euler angles so I can adjust the angles to match the angles they should change
Vector3 myEulerAngles = myQuaternion.eulerAngles;

//This is where I create a new Vector3 trying to remap the angles
Vector3 adjustedEulerAngles = new Vector3(myEulerAngles.z, myEulerAngles.y, myEulerAngles.x); ;

//This is where I transfor the Euler angles back to quaternions
Quaternion newQuaternion = Quaternion.Euler(adjustedEulerAngles);

//This is where I set the location rotation of the object to the "adjusted" quaterion
transform.localRotation = newQuaternion;

Вы хоть представляете, почему этот код не работает? Если нет, какие хорошие ресурсы, где я могу лучше понять, как понять значения, которые отправляет мне телефон Android?

Это код, который я использую на телефоне Android. Эти значения являются результатами датчика TYPE_GAME_ROTATION_VECTOR.

public void onSensorChanged(SensorEvent sensorEvent) {
    for (int i=0; i<4; i++) {
        orientations[i] = sensorEvent.values[i];
    }
    String temp = String.valueOf(orientations[0]);
    Log.i("STATE", temp);
}

Я проверил документацию Android по этому датчику, но это не очень помогло:

https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_GAME_ROTATION_VECTOR

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

https://thewikihow.com/video_C7JQ7Rpwn2k?t=35m32s

https://thewikihow.com/video_kYOtk5a6_x4

Но я все еще не могу понять, что у меня есть кватернион и как правильно преобразовать его в 3D-объект.

Мы будем очень благодарны за любые предложения, и если я сделал что-то не так, создавая свой пост, дайте мне знать, так как это мой первый вопрос по stackoverflow. Спасибо!

Я раньше работал с unity3d и кватернионами и обнаружил, что работы с углами Эйлера было достаточно. Unity3D преобразует углы Эйлера в кватернионы и обрабатывает все вращение, поэтому нет необходимости возиться с кватернионами.

JSmith 18.03.2018 20:25

Я попытался преобразовать данные в приложении Android в углы Эйлера, и это сработало. Проблема в том, что когда я использую его в Unity, я сталкиваюсь с проблемой блокировки кардана и не могу повернуть объект на 360º по одной из осей. Вот почему я решил использовать кватернионы, так как мне нужно вращение на 360 градусов по всем осям.

Guilherme Schaidhauer Castro 18.03.2018 21:10

Я читал, что в единстве используются кватернионы внутри. Вместо создания новых кватернионов вы можете попробовать что-то вроде object.rotation = Quaternion.Slerp (object.rotation, Quaternion.Euler (x, y, z), Time.deltaTime); x, y и z - углы Эйлера.

JSmith 18.03.2018 21:23
0
3
381
0

Другие вопросы по теме