Я пишу простой синтаксический анализатор BVH на C #, используя платформу XNA.На данный момент мне удалось проанализировать все данные, и моя цель - выяснить глобальные координаты всех суставов в скелете.
Проблема, с которой я сталкиваюсь, заключается в том, что кости, кажется, не учитывают ротацию своих родителей.Например, если я двигаю нижнюю ногу, я ожидаю, что моя нога также изменит ориентацию и сохранит одинаковые углы между ступней и нижней ногой.Что я замечаю, так это то, что перемещение костных суставов правильное, но глобальное вращение кости такое же, как и локальное вращение кости.Изображение ниже может помочь вам понять, в чем проблема:
скелет http://i40.tinypic.com/18kv2d.png
примечание: в подписи к картинке есть ошибка, она должна читать "левая верхняя часть ноги вращается вокругось z "не ось x.
Я бы ожидал, что часть голени также будет повернута на 1 радиан в результате изменения ориентации ее родителей.
Таким образом, кодниже (я использую XNA и C #):
foreach (Bone b in bones)
{
//Calculate the local transform matrix
b.localTransform = Matrix.CreateTranslation(b.Offset) * Matrix.CreateRotationZ(MathHelper.ToRadians(b.z)) * Matrix.CreateRotationY(MathHelper.ToRadians(b.y)) * Matrix.CreateRotationX(MathHelper.ToRadians(b.x));
Bone parent = b.parent;
if (parent != null)
{
//Calculate global transform matrix
b.globalTransform = parent.globalTransform * b.localTransform;
b.location = b.globalTransform.Translation;
lines.Add(new Tuple<Vector3, Vector3>(parent.location, b.location));
}
}
Каждая кость предполагает, что глобальное преобразование ее родителей правильное, поскольку список упорядочен, поэтому родители всегда идут перед детьми.Корневая кость не имеет вращений и смещений, и ее глобальное преобразование уже установлено на основе этого.Мне интересно, что я здесь делаю не так?
Я сделал простой пример, используя только 2D:
Matrix bone1 = Matrix.CreateTranslation(new Vector3(3, 0, 0)) * Matrix.CreateRotationZ(1);
Matrix bone2 = Matrix.CreateTranslation(new Vector3(3, 0, 0)) * Matrix.CreateRotationZ(1);
lines.Add(new Tuple<Vector3, Vector3>(Vector3.Zero, bone1.Translation));
lines.Add(new Tuple<Vector3, Vector3>(bone1.Translation, (bone1 *bone2).Translation));
Рисование этого на экране показывает то, что я ожидаю.1-я кость вращается на 1 радиан вокруг источника, 2-я кость вращается на 2 радиана вокруг источника.
Я использую нижеследующее в качестве справки для анализа и интерпретации данных BVH: http://www.dcs.shef.ac.uk/intranet/research/resmes/CS0111.pdf