Небольшие ошибки вращения, вызывающие деформацию модели

(Возможный дубликат: Вращение матрицы 4×4 вызывает масштабирование во времени )

Здравствуйте все. Я пытался привести модель в позу, отличную от позы связывания. В настоящее время я использую первый кадр из файла анимации и пытаюсь установить модель в исходную позу.

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

int targetFrame = CONST_TEST_FRAME_NUMBER;

// root bone
PMXBone   *b  = pmxInfo.bones[0];
BoneFrame *bf = getBoneFrame(targetFrame, b->name);

b->absoluteForm = b->relativeForm;
Bone[0] = b->absoluteForm * invBindPose[0];// other bones
for (size_t i = 1; i < pmxInfo.bone_continuing_datasets; i++)
{
b  = pmxInfo.bones[i];
PMXBone *parent = pmxInfo.bones[b->parentBoneIndex];
bf = getBoneFrame(targetFrame, b->name);

if(bf!=NULL)
{
b->finalRotation = bf->quaternion * parent->finalRotation;glm::vec4 homoPosition=glm::vec4(b->position + bf->translation, 1.0); //position in homogeneous coordinates
glm::vec4 localPosition=glm::rotate(parent->finalRotation,homoPosition);

b->relativeForm[3][0]=localPosition[0];
b->relativeForm[3][1]=localPosition[1];
b->relativeForm[3][2]=localPosition[2];
b->relativeForm[3][3]=localPosition[3];

b->absoluteForm = (b->relativeForm * glm::toMat4(bf->quaternion)) * parent->absoluteForm;

Bone[i] = b->absoluteForm * invBindPose[i];
}
else
{
b->finalRotation = parent->finalRotation;

glm::vec4 homoPosition=glm::vec4(b->position,1.0); //position in homogeneous coordinates
glm::vec4 localPosition=glm::rotate(b->finalRotation,homoPosition);

b->relativeForm[3][0]=localPosition[0];
b->relativeForm[3][1]=localPosition[1];
b->relativeForm[3][2]=localPosition[2];
b->relativeForm[3][3]=localPosition[3];

b->absoluteForm = b->relativeForm * parent->absoluteForm;

Bone[i] = b->absoluteForm * invBindPose[i];
}
}
}

Чтобы помочь разъяснить код некоторые:

  • b-> position — это glm :: vec3, содержащий положение кости в
    Местное / костное пространство, относительно родительской кости.
  • BF содержит информацию о преобразовании для 1 кость в 1
    Рамка. Другими словами, вы должны получить несколько костей, чтобы получить
    преобразование информации для все кости в 1 Рамка.
  • bf-> quaternion — это 4-float glm :: quat, содержащий вращательную
    информация для костей в анимации. Другими словами, это
    содержит информацию о том, как нужно повернуть кость, чтобы получить модель
    от его привязки к текущей позе.
  • Аналогично, bf-> translation, glm :: vec3, содержит переводческий
    информация для костного каркаса. Потому что человеческие скелеты жесткие,
    большинство значений для bf-> translation установлены в (0,0,0).
  • lativeForm и absoluteForm ссылаются на локальную и глобальную матрицы.
    трансформированных костей, соответственно. Перед этим фрагмент кода
    run ,lativeForm — это просто b-> позиция, преобразованная в матрицу, и
    absoluteForm — это матрица Bind Pose для кости.

Вот изображение того, как модель выглядит с этим кодом:
http://imgur.com/tbur5Lf

В качестве дополнения, вот изображение одной кости в модели, которая трансформируется с использованием этого кода (вместо bf использовался кватернион с управлением от клавиатуры): http://t.co/wf38ibGoyc

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

РЕДАКТИРОВАТЬ:
Я загружаю видео, которое демонстрирует успех моей программы в преобразованиях одной кости и проблемы с составными преобразованиями. Когда загрузка будет завершена, она будет по адресу: http://youtu.be/8Cv3jMYcz64

0

Решение

2ч спас мне день

void setModelToKeyFrame(glm::mat4 Bone[], GLuint &shaderProgram, PMXInfo &pmxInfo, VMDInfo &vmdInfo)
{

int targetFrame = CONST_TEST_FRAME_NUMBER;
glm::mat4 aniMatrix;

// root bone
PMXBone   *b  = pmxInfo.bones[0];
BoneFrame *bf = getBoneFrame(targetFrame, b->name);

b->absoluteForm = b->relativeForm;
if(bf!=NULL)
{
b->finalRotation = bf->quaternion;

b->relativeForm = glm::translate( b->position ) * glm::toMat4(bf->quaternion);
b->absoluteForm = glm::translate( bf->translation + b->position ) * glm::toMat4(bf->quaternion);
Bone[i] = glm::translate( bf->translation + b->position ) * glm::toMat4(bf->quaternion) * glm::translate( -b->position );
}
Bone[0] = b->absoluteForm * invBindPose[0];// other bones
for (size_t i = 1; i < pmxInfo.bone_continuing_datasets; i++)
{
b  = pmxInfo.bones[i];
PMXBone *parent = pmxInfo.bones[b->parentBoneIndex];
bf = getBoneFrame(targetFrame, b->name);

if(bf!=NULL)
{
b->finalRotation = bf->quaternion * parent->finalRotation;

b->relativeForm = glm::translate( bf->translation + b->position - parent->position ) * glm::toMat4(bf->quaternion);
b->absoluteForm = parent->absoluteForm * glm::translate( bf->translation + b->position - parent->position ) * glm::toMat4(bf->quaternion);
Bone[i] = parent->absoluteForm * glm::translate( bf->translation + b->position - parent->position ) * glm::toMat4(bf->quaternion) * glm::translate( -b->position );
}
else
{
b->finalRotation = parent->finalRotation;

b->relativeForm = glm::translate( b->position - parent->position );
b->absoluteForm = parent->absoluteForm * glm::translate( b->position - parent->position );
Bone[i] = parent->absoluteForm * glm::translate( b->position - parent->position ) * glm::translate( -b->position );
}

}
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]