Я пишу собственный скрипт для экспорта моделей и анимации Blender в игру, которая работает с использованием OpenGL.
Я знаю, что Blender использует систему Z-up, тогда как OpenGL в моей игре использует систему Y-up. Я легко могу исправить положение сетки модели и кости с помощью вращения вокруг оси X, равного -π / 2, что правильно отображает модель.
Однако в Blender кость на ноге моего персонажа, параллельная полу, имеет вращение эйлера X, равное 0, а кость, которая перпендикулярна полу, имеет вращение эйлера X, равное -π / 2 (или π / 2 ).
В игре нога персонажа, которая параллельна полу, имеет вращение Эйлера X -π / 2 (или π / 2), а кость, которая перпендикулярна полу, имеет вращение 0.
Здесь левая нога модели параллельна полу с тем же поворотом эйлера XYZ, что и левая нога в Blender (перпендикулярно полу):
Скрипт экспорта blender для вращений костей в каждом кадре:
for f in range(scene.frame_start, scene.frame_end + 1):
bpy.context.scene.frame_set(f);
bpy.context.scene.update();
for i in range(len(arm.pose.bones)):
bone = arm.pose.bones[i]
out.write(str(boneIDs[bone.name]) + ","); # ID of the bone
out.write(VecToStringComma(bone.matrix.to_euler())) # bone rotation
out.write("\n")
И загружая его в C #, матрица вращения кости перекомпоновывается со следующим кодом:
for (int i = 0; i <= frameCount; i++)
{
Frame frame = new Frame();
var parts = r[read].Split(',');
read++;
for (int p = 0; p < parts.Length - 1; p += 4)
{
FrameDeform fd = new FrameDeform();
fd.DeformerID = int.Parse(parts[p]);
Vector3 rot = new Vector3(double.Parse(parts[p + 1]), double.Parse(parts[p + 2]), double.Parse(parts[p + 3]));
fd.Rotation = Matrix4.CreateRotationX(rot.X) * Matrix4.CreateRotationY(rot.Y) * Matrix4.CreateRotationZ(rot.Z);
frame.FrameDeforms.Add(fd);
}
anim.Frames.Add(frame);
}
Кадр 0 в Blender выглядит следующим образом:
Кадр 0 в игре выглядит так:
Я знаю, что в настоящее время я не применяю никаких изменений к значениям вращения, однако я вижу, что ноги следуют по правильному пути движения в игре, но по неправильной оси.
Вращение значений вращения на -π / 2 вокруг оси X не помогает, поскольку значения X остаются неизменными.
Любая помощь была бы невероятно признательна, так как я уже давно борюсь с этой проблемой.
Обновление
При загрузке модели я не применяю поворотов вокруг оси X. Вместо этого во время выполнения я применяю вращение -π / 2 вокруг оси X, что происходит в шейдере:
vec3 pos = (zMat * bones[id] * vec4(aPosition, 1.0)).xyz
Однако это дает мне следующий результат (только при анимации туловища):