骨骼动画
skeletal animation
本文关键字:动画 更新时间:2023-10-16
我是骨骼动画术语的新手,我已经读到了,要使用骨骼对网格进行动画,我必须使用骨骼的层次结构场景图,然后为了变形网格,我必须在插值之前获得骨头的逆绝对矩阵(我认为这就是他们所说的姿势)乘以骨头的插值绝对矩阵,以获得过渡矩阵和变形。我将不得不将顶点乘以过渡矩阵乘以乘以重量的重量,并将所有这些结果与所有其他骨变形相同的骨头总和。
更具体地要获得每个骨头的绝对性,我要这样做
void CNode::update()
{
if(this->Parent!=null)
absMatrix = this->Parent->absMatrix * relativeMatrix;
else
absMatrix = RelativeMatrix;
for(int n=0; n<childs.count; n++)
{
childs[n]->update();
}
}
现在,我在任何一次更改relativematrix的插值之前就获得了此Absmatrix矩阵的倒数因此,要执行顶点变形是此函数
void CMesh::skinMesh(){
CVec3 vec;
for(int n=0; n < vertex.count; n++)
{
vec.clear();
for(int i=0; i < vertex[n].weight.count && vertex[n].bindBone[i] ; i++)
{
vec+= vertex[n].vec * vertex[n].bindBone[i]->transitionMatrix * vertex[n].weight[i];
}
outVertex[n] = vec;
}
现在对我不起作用,因为每个顶点围绕网轴的中心旋转,而不是骨头的父母,骨头变形了顶点,我认为这是合乎逻辑的transition = inverabs *absoultematrix将为我带来骨骼因插值而获得的旋转量骨头变形的父母,请帮助我。
因此,这就是我进行插值的方式,而不是绝对矩阵,而是对RelativeMatrix的代码i更新的代码是上面的。
//CAnimateObject is a decendent class of CNode
void CAnimateObject::UpdateFrame(unsigned AniNum, float Time)
{
float fInterp;
if(m_AniCount > AniNum)
{
CKeyFrame *CurAni = &Ani[ AniNum ];
if(CurAni->Pos.list.count>0)
{
CFrame<CVector3>::CKEY *begin, *end;
if( CurAni->Pos.getBetweenKeys(&begin, &end, Time, fInterp)){
m_Pos.x = begin->Object->x + (end->Object->x - begin->Object->x) * fInterp;
m_Pos.y = begin->Object->y + (end->Object->y - begin->Object->y) * fInterp;
m_Pos.z = begin->Object->x + (end->Object->z - begin->Object->z) * fInterp;
}
}
if(CurAni->Scale.list.count>0)
{
CFrame<CVector3>::CKEY *begin, *end;
if( CurAni->Scale.getBetweenKeys(&begin, &end, Time, fInterp)){
m_Scale.x = begin->Object->x + (end->Object->x - begin->Object->x) * fInterp;
m_Scale.y = begin->Object->y + (end->Object->y - begin->Object->y) * fInterp;
m_Scale.z = begin->Object->x + (end->Object->z - begin->Object->z) * fInterp;
}
}
if(CurAni->Rot.list.count > 1)
{
CFrame<CQuaternion>::CKEY *begin, *end;
if( CurAni->Rot.getBetweenKeys(&begin, &end, Time, fInterp)){
m_Qrel.SLERP(*begin->Object, *end->Object, fInterp);
}
}else
if(CurAni->Rot.list.count==1)
m_Qrel = *(CQuaternion*)CurAni->Rot.list.start[0].Object;
}
CMatrix4 tm, scale;
scale.identity();
tm.identity();
scale.Scale(m_Scale.Get());
tm.fromQuaternion(m_Qrel);
m_Rel = tm * scale;
m_Rel.Translate(m_Pos);
}
是的,我这样做了,并将骨骼乘以逆,然后乘以绝对膜,并且可以很好地工作,但是在许多乘法中都在发生,例如。
。//inversePose is the absoluteMatrix before applying the interpolation of the relative matrix
void CMesh::skinMesh(){
CVec3 vec;
for(int n=0; n < vertex.count; n++)
{
outVertex[n].clear();
for(int i=0; i < vertex[n].weight.count && vertex[n].bindBone[i] ; i++)
{
vec = vertex[n].vec3 * vertex[n].bindBone[i]->inversePose;
vec = vec * vertex[n].bindBone[i]->absMatrix * vertex[n].weight[i];
outVertex[n]+= vec;
}
}
该代码现在正常工作,看起来我的矩阵乘法序列错误,因为它像inverpose * absolutematrx一样,现在是错误的,现在是absolutematrx * inverpose * inverpose且工作正常
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 使用 GLUT 使用键停止动画?
- 使用对象数组对 SFML 进行动画处理
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 如何减慢从 BVH 文件读取的 opengl 动画?
- 如何检测是否在缓冲绘画动画中绘制最后一帧?
- 从精灵表在 sfml 中为精灵制作动画
- Qt3D 骨骼动画
- ASCII 旋转光标 (TUI) 动画出现问题
- 带有 std::cout 的多线程控制台文本动画
- 有没有办法像动画一样移动控制台窗口?
- 围绕特定轴对 qt3d 旋转进行动画处理
- 如何在Qt中设置围绕固定点的线的动画
- 试图用c++制作一个动画加载圈
- 精灵动画查看器应该使用哪些Qt小部件
- 骨骼动画:变换矩阵(collada)之间的插值
- 使用增量时间的对象动画
- 精灵没有动画
- 使用 GDI+ 在C++中制作流畅的动画
- 是否可以在QT GUI应用程序中处理事件时播放加载动画指示器?