0

(重複の可能性: 4x4 マトリックスを回転させると、時間の経過とともにスケーリングが発生します)

こんにちは、みんな。モデルをバインド ポーズ以外のポーズにしようとしています。現在、アニメーション ファイルの最初のフレームを使用して、モデルをその初期ポーズに設定しようとしています。

私の数学の方程式は今では正しいと信じています。単一のボーンの変換は完全に機能します (子は本来のように追従します)。ただし、Compound Transformations (子が変換され、その親も変換される) では、非常に幼い子供が非常に変形しているように見えます。(たとえば、手首、肘、肩のボーンも変形したモデルの指)。

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->position は、親ボーンに対するローカル/ボーン空間でのボーンの位置を含む glm::vec3 です。
  • bf には、1 フレームの1ボーンの変換情報が含まれます。つまり、 1フレーム内のすべてのボーンの変換情報を取得するには、複数のボーン フレームを取得する必要があります。
  • bf->quaternion は、アニメーションのボーン フレームの回転情報を含む 4 つの浮動小数点 glm::quat です。つまり、モデルをバインド ポーズから現在のポーズにするためにボーンをどのように回転させる必要があるかについての情報が含まれています。
  • 同様に、glm::vec3 である bf->translation には、ボーン フレームの並進情報が含まれています。人間の骨格は剛体であるため、bf->translation のほとんどの値は (0,0,0) に設定されています。
  • relativeForm と absoluteForm は、それぞれ、変換されたボーンのローカル マトリックスとグローバル マトリックスを参照します。このコード スニペットを実行する前に、relativeForm は単純に b->position をマトリックスに変換し、absoluteForm はボーンのバインド ポーズ マトリックスです。

このコードでモデルがどのように表示されるかのイメージを次に示します: http://imgur.com/tbur5Lf

おまけとして、このコードを使用してモデル内の単一のボーンを変換した画像を次に示します (bf の代わりに、キーボード制御の四元数が使用されました): http://t.co/wf38ibGoyc

ここまで来るのに 2 週間ほどかかりました。ありがとうございます。他に提供する必要がある情報があればお知らせください。

編集: 単一の骨の変換における私のプログラムの成功と、複合変換の問題を示すビデオをアップロードしています。アップロードが完了すると、http: //youtu.be/8Cv3jMYcz64になります。

4

1 に答える 1

0

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

    }
}
于 2013-07-31T21:22:01.880 に答える