(Возможный дубликат: Вращение матрицы 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];
}
}
}
Чтобы помочь разъяснить код некоторые:
Вот изображение того, как модель выглядит с этим кодом:
http://imgur.com/tbur5Lf
В качестве дополнения, вот изображение одной кости в модели, которая трансформируется с использованием этого кода (вместо bf использовался кватернион с управлением от клавиатуры): http://t.co/wf38ibGoyc
Мне потребовалось две недели, чтобы пройти этот путь, поэтому я очень ценю любую помощь. Спасибо, и дайте мне знать, если есть какая-либо другая информация, которую я должен предоставить.
РЕДАКТИРОВАТЬ:
Я загружаю видео, которое демонстрирует успех моей программы в преобразованиях одной кости и проблемы с составными преобразованиями. Когда загрузка будет завершена, она будет по адресу: http://youtu.be/8Cv3jMYcz64
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 );
}
}
}
Других решений пока нет …