Assimp кости анимация - PullRequest
       35

Assimp кости анимация

0 голосов
/ 27 января 2020

Я следую открытому учебнику GL, но меняю порядок умножения матриц, так как использую прямой x. Я нахожусь в C ++.

Это код, который я следую: http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html

И это код, который у меня есть:

               void jointTransform(float timeInSeconds, 
              std::vector<DirectX::XMMATRIX>& transformM, aiAnimation* ani, UINT nrOfJoints, 
             std::vector<joints>& jointInfo, const aiScene* scenePtr)
            {


           DirectX::XMMATRIX iD = DirectX::XMMatrixIdentity();

float ticksPerSecond = (float)ani->mTicksPerSecond;

if (ticksPerSecond == 0)
{
    ticksPerSecond = 30;
}

float timeInTicks = timeInSeconds * ticksPerSecond;

float animationTime = fmod(timeInTicks, (float)ani->mDuration);



readNodeHeiarchy(animationTime, scenePtr->mRootNode, iD, jointInfo, ani, scenePtr);

transformM.resize(nrOfJoints);

for (UINT i = 0; i < transformM.size(); i++)
{
    transformM[i] = jointInfo[i].transformFinal;
}




      }
        void readNodeHeiarchy(float time, const aiNode* node, DirectX::XMMATRIX parentMat, 
       std::vector<joints>& jointInfo, aiAnimation* ani, const aiScene* scenePtr)
       {
       std::string nodeNameString = node->mName.data;
      //



     //aiString nName = node->mName;

  aiMatrix4x4 nodeTransform = node->mTransformation;
     DirectX::XMMATRIX combined;

   combined = DirectX::XMMatrixSet(nodeTransform.a1, nodeTransform.a2, nodeTransform.a3, 
    nodeTransform.a4,
    nodeTransform.b1, nodeTransform.b2, nodeTransform.b3, nodeTransform.b4,
    nodeTransform.c1, nodeTransform.c2, nodeTransform.c3, nodeTransform.c4,
    nodeTransform.d1, nodeTransform.d2, nodeTransform.d3, nodeTransform.d4);

const aiNodeAnim* joint = nullptr;


for (UINT i = 0; i < ani->mNumChannels; i++)
{


    if (nodeNameString == ani->mChannels[i]->mNodeName.data)
    {
        joint = ani->mChannels[i];

    }


       }

       if (joint)
       {



          DirectX::XMMATRIX S;
            DirectX::XMMATRIX R;
             DirectX::XMMATRIX T;

             //scale

            aiVector3D scaleV;
            calcLerpScale(scaleV, time, joint);
            S = DirectX::XMMatrixScaling(scaleV.x, scaleV.y, scaleV.z);


         //rotate
        aiQuaternion rotationQ;
       calcLerpRot(rotationQ, time, joint);

       DirectX::XMVECTOR q;

       q = DirectX::XMVectorSet(rotationQ.x, rotationQ.y, rotationQ.z, rotationQ.w);

       R = DirectX::XMMatrixRotationQuaternion(q);

      //translate


    aiVector3D transV;

    calcLerpTrans(transV, time, joint);

    T = DirectX::XMMatrixTranslation(transV.x, transV.y, transV.z);


    combined = S * R * T;



             }

            DirectX::XMMATRIX globalTransform = combined * parentMat;







               if (jointInfo[jointInfo.size() - 1].name.C_Str() != nodeNameString)
            {



         for (UINT i = 0; i < jointInfo.size(); i++)
        {
        if (jointInfo[i].name.C_Str() == nodeNameString)
        {

            aiMatrix4x4 off = jointInfo[i].offsetM;
            DirectX::XMMATRIX offset;
            offset = DirectX::XMMatrixSet(off.a1, off.a2, off.a3, off.a4,
                off.b1, off.b2, off.b3, off.b4,
                off.c1, off.c2, off.c3, off.c4,
                off.d1, off.d2, off.d3, off.d4);

            DirectX::XMMATRIX rootMInv;
            aiMatrix4x4 rootInv = scenePtr->mRootNode->mTransformation.Inverse();
            rootMInv = DirectX::XMMatrixSet(rootInv.a1, rootInv.a2, rootInv.a3, rootInv.a4,
                rootInv.b1, rootInv.b2, rootInv.b3, rootInv.b4,
                rootInv.c1, rootInv.c2, rootInv.c3, rootInv.c4,
                rootInv.d1, rootInv.d2, rootInv.d3, rootInv.d4);


            jointInfo[i].transformFinal = offset * globalTransform * rootMInv;



           }


            }


            }

           for (UINT i = 0; i < node->mNumChildren; i++)
        {

           readNodeHeiarchy(time, node->mChildren[i], globalTransform, jointInfo, ani, scenePtr);

           }



           }
         void calcLerpScale(aiVector3D& scale, float aniTime, const aiNodeAnim* joint)
        {

         if (joint->mNumScalingKeys == 1)
          {
            scale = joint->mScalingKeys[0].mValue;
           return;
       }

       UINT scaleInd = findIndexS(aniTime, joint);
          UINT nextScale = scaleInd + 1;

        assert(nextScale < joint->mNumScalingKeys);

       float deltaTime = (float)joint->mScalingKeys[nextScale].mTime - (float)joint- 
      >mScalingKeys[scaleInd].mTime;
          float factor = (aniTime - (float)joint->mScalingKeys[scaleInd].mTime) / deltaTime;

       assert(factor >= 0.0f && factor <= 1.0f);

       const aiVector3D& startScaleV = joint->mScalingKeys[scaleInd].mValue;
       const aiVector3D& endScaleV = joint->mScalingKeys[nextScale].mValue;

        //interpolate

         aiVector3D Delta = endScaleV - startScaleV; // 

        scale = startScaleV + (factor * Delta); 

      scale.Normalize();




       }
      void calcLerpRot(aiQuaternion& rotation, float aniTime, const aiNodeAnim* joint)
      {
      if (joint->mNumRotationKeys == 1)
     {
    rotation = joint->mRotationKeys[0].mValue;

    return;
    }

    UINT rotIndex = findIndexRot(aniTime, joint);
    UINT nextRot = (rotIndex + 1);


    assert(nextRot < joint->mNumRotationKeys);

    float deltaTime = (float)joint->mRotationKeys[nextRot].mTime - (float)joint- 
    >mRotationKeys[rotIndex].mTime;

    float factor = (aniTime - (float)joint->mRotationKeys[rotIndex].mTime) / deltaTime;

   assert(factor >= 0.0f && factor <= 1.0f);


   const aiQuaternion& StartRotationQ = joint->mRotationKeys[rotIndex].mValue;
   const aiQuaternion& EndRotationQ = joint->mRotationKeys[nextRot].mValue;

   aiQuaternion::Interpolate(rotation, StartRotationQ, EndRotationQ, factor);

   rotation.Normalize();
   }
    void calcLerpTrans(aiVector3D& translation, float aniTime, const aiNodeAnim* joint)
    {
   if (joint->mNumPositionKeys == 1)
   {
    translation = joint->mPositionKeys[0].mValue;

    return;
   }

   UINT transIndex = findIndexT(aniTime, joint);
   UINT nextTrans = (transIndex + 1);


   assert(nextTrans < joint->mNumPositionKeys);

   float deltaTime = (float)joint->mPositionKeys[nextTrans].mTime - (float)joint- 
 >mPositionKeys[transIndex].mTime;

float factor = (aniTime - (float)joint->mPositionKeys[transIndex].mTime) / deltaTime;

assert(factor >= 0.0f && factor <= 1.0f);


const aiVector3D& startTransV = joint->mPositionKeys[transIndex].mValue;
const aiVector3D& endTransV = joint->mPositionKeys[nextTrans].mValue;

//interpolate

aiVector3D Delta = endTransV - startTransV;

translation = startTransV + (factor * Delta);

translation.Normalize();



     }
     UINT findIndexRot(float aniTime, const aiNodeAnim* joint)
     {

assert(joint->mNumRotationKeys > 0);

for (UINT i = 0; i < joint->mNumRotationKeys - 1; i++)
{
    if (aniTime < (float)joint->mRotationKeys[i + 1].mTime)
    {
        return i;
    }


}


assert(0);
    }
       UINT findIndexS(float aniTime,const aiNodeAnim* joint)
        {

assert(joint->mNumScalingKeys > 0);

for (UINT i = 0; i < joint->mNumScalingKeys - 1; i++)
{
    if (aniTime < (float)joint->mScalingKeys[i + 1].mTime)
    {
        return i;
    }


}


assert(0);







        }
         UINT findIndexT(float aniTime,const aiNodeAnim* joint)
        {

assert(joint->mNumPositionKeys > 0);

for (UINT i = 0; i < joint->mNumPositionKeys - 1; i++)
{
    /*
    OutputDebugStringA("\n");
    OutputDebugStringA(std::to_string(aniTime).c_str());
    OutputDebugStringA("\n");
    OutputDebugStringA("\n");
    OutputDebugStringA(std::to_string((float)joint->mPositionKeys[i + 1].mTime).c_str());
    OutputDebugStringA("\n");
    */

    if (aniTime < (float)joint->mPositionKeys[i + 1].mTime)
    {
        return i;
    }


}


assert(0);



  }

Код здесь немного запутан, я также умножаю, как 52 матрицы, которые устанавливаются при обновлении. И я собираю объединенную информацию, сохраняя ее в правильных вершинах.

Я не следовал точно коду, вы видите какие-либо очевидные ошибки?

Вот остальные:

                           for (UINT k = 0; k < vertexVector.size(); k++)
    {




        vertexVector[k].joints.x = 0;
        vertexVector[k].joints.y = 0;
        vertexVector[k].joints.z = 0;
        vertexVector[k].joints.w = 0;








    }



    std::vector<joints> jointInfo;
    nrOfJs = currentMesh->mNumBones;
    for (UINT k = 0; k < currentMesh->mNumBones; k++)
    {

        aiBone* bone = currentMesh->mBones[k];

        joints joint;
        joint.name = bone->mName;
        joint.offsetM = bone->mOffsetMatrix;

        jointInfo.push_back(joint);




        for (UINT m = 0; m < bone->mNumWeights; m++)
        {
            aiVertexWeight weight = bone->mWeights[m];



            for (UINT n = 0; n < currentMesh->mNumVertices; n++)
            {

                if (n == weight.mVertexId)
                {

                    if (vertexVector[n].joints.x == 0)
                    {


                        vertexVector[n].joints.x = weight.mVertexId;
                        vertexVector[n].weights.x = weight.mWeight;

                    }
                    else if (vertexVector[n].joints.y == 0)
                    {
                        vertexVector[n].joints.y = weight.mVertexId;
                        vertexVector[n].weights.y = weight.mWeight;
                    }
                    else if (vertexVector[n].joints.z == 0)
                    {
                        vertexVector[n].joints.z = weight.mVertexId;
                        vertexVector[n].weights.z = weight.mWeight;
                    }
                    else if (vertexVector[n].joints.w == 0)
                    {
                        vertexVector[n].joints.w = weight.mVertexId;
                        vertexVector[n].weights.w = weight.mWeight;
                    }
                    else
                    {
                        continue;
                    }


                }


            }


                         std::vector<joints> copyJ = sp.getJ(0);

jointTransform(runningTime, nrOfTransforms,sp.getAni(0) , nrOfJs, copyJ, sp.get(1));




for (UINT i = 0; i < nrOfTransforms.size(); i++)
{

    constants.skinMatrix[i] = nrOfTransforms[i];

}

Результатом сейчас является то, что у меня мерцает меня sh, который похож на грязную липучку, как будто все значения tra sh.

против:

                         float4x4 jointTrans = float4x4(ID);

if (input.joints[0] != 0)
{
    jointTrans = float4x4(skinMatrix[input.joints.x]) * input.weights.x;



}
if (input.joints[1] != 0)
{
    jointTrans += float4x4(skinMatrix[input.joints.y]) * input.weights.y;
}
if (input.joints[2] != 0)
{
    jointTrans += float4x4(skinMatrix[input.joints.z]) * input.weights.z;
}
if (input.joints[3] != 0)
{
    jointTrans += float4x4(skinMatrix[input.joints.w]) * input.weights.w;
}                                       
...