旋转中的小误差导致模型变形
Small errors in rotation causing model deformation
(可能重复:旋转4x4矩阵导致随时间缩放)
大家好。我一直在尝试让一个模型进入一个姿势,而不是它的绑定姿势。目前,我正在使用动画文件中的第一帧,并试图将模型设置为初始姿势。
我相信我的数学方程式现在是正确的。改造一块骨头效果很好(孩子们按照它应该做的那样做)。然而,使用复合变换(其中子对象被变换,其父对象也被变换),非常小的孩子似乎高度变形。(例如,当手腕、肘部和肩部骨骼也已变换时,模型的手指。)
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->位置是一个glm::vec3,包含骨骼在其局部/骨骼空间,相对于父骨骼
- bf包含1中1骨骼的转换信息框架换句话说,必须获得多个骨骼框架才能获得1帧中所有骨骼的变换信息
- bf->四元数是一个包含旋转的4浮点glm::quat动画中骨骼帧的信息。换句话说包含有关必须如何旋转骨骼才能获得模型的信息从其绑定姿势到当前姿势
- 类似地,bf->translation,一个glm::vec3,包含translation骨骼框架的信息。因为人类骨骼是刚性的,bf->translation的大多数值都设置为(0,0,0)
- relativeForm和absoluteForm指的是局部矩阵和全局矩阵分别为变换骨骼的。在此代码段之前运行时,relativeForm只需b->位置转换为矩阵,并且absoluteForm是骨骼的绑定姿势矩阵
以下是使用此代码显示模型的图像:https://i.stack.imgur.com/tPJ1t.jpg
作为额外的功能,这里是使用此代码转换的模型中单个骨骼的图像(使用了键盘控制的四元数而不是bf):http://t.co/wf38ibGoyc
我花了整整两周的时间才走到这一步,所以我非常感谢任何帮助。谢谢,如果我需要提供任何其他信息,请告诉我。
编辑:我正在上传一段视频,展示我的程序在单骨骼转换方面的成功,以及复合转换的问题。上传完成后,它将位于:http://youtu.be/8Cv3jMYcz64
2ch为我节省了一天:
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 );
}
}
}
相关文章:
- QTableView:endMoveRows在模型中重置水平页眉大小
- 将IBM Rhapsody模型集成到VS 2019中
- 旋转模型矩阵时的形状失真
- 成员函数调用和C++对象模型
- 连接 dockerized 模型和 dockerized 数据库时出现"无法 SQLConnect"错误
- 打印 ONNXRUNTIME::图形没有模型
- C++内存模型和位字段的最大序列
- 使用SIR模型的疾病爆发模拟
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 如何在 ECS 模型中组织实体?
- 在官方张量流 resnet50 模型上运行 tflite 精度工具
- Libtorch:如何加载ONNX模型?
- 使用 assimp 加载模型 - 不需要提升?
- 如何将经过训练的机器学习模型保存在python中并将其加载到C++中进行预测?
- C++内存模型中的确切规则阻止在获取操作之前重新排序
- 如何更改古罗比C++模型中的目标值系数
- 如何在 openGL 中围绕全局轴旋转模型?
- 我们可以将阈值应用于色彩空间模型的单个组件(如 RGB 和 LAB)吗?
- 三维模型平移使对象变形
- 旋转中的小误差导致模型变形