скелетная анимация

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

чтобы быть более конкретным, чтобы получить абсолют каждой кости, я делаю это

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();
}
}

теперь я получаю инверсию этой матрицы 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 даст мне величину поворота, которое получит кость благодаря интерполяции, поэтому, предполагая, что она будет поворачиваться на 20 градусов, вершины будут вращаться на 20 градусов от начала координат, так что я предполагаю, что мне чего-то не хватает, чтобы заставить вращаться вершины вокруг Родитель кости, которая их деформирует, пожалуйста, помогите мне.

так вот, как я делаю интерполяцию, то есть не для абсолютной матрицы, а для относительной матрицы код, который я обновляю, — это код выше.

//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;
}

}

2

Решение

код работает сейчас, похоже, что мое умножение матриц было в неправильном порядке, потому что оно делало это как inverPose * absoluteMatrx и было неправильно, теперь это absoluteMatrx * inverPose и работает нормально

0

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

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

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