Animation

Dolphin Animation

頂点データをブレンドして Dolphin Animation です。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの説明

  1. 3体の Dolphin Model の頂点座標をブレンドしながらアニメーションします。
    DirectX9 の初期に、私が最も感動したアニメーションです。
    プロジェクトを作成して Load_Vertex.h と Load_Vertex.cpp を組み込んで下さい。
    "dolphin1.x", "dolphin2.x", "dolphin3.x" のモデルを組み込んで、コンテンツを True に設定して下さい。
    プロジェクトを生成は Win10 Template を参照して下さい。
  2. Sample3DSceneRenderer.h にモデルの領域を定義します。
    m_totalRotation はアニメーションで使うために Update() で時刻を保存する領域です。
            Load_Vertex *model[3];
            double  m_totalRotation;
    
  3. "dolphin1.x", "dolphin2.x", "dolphin3.x" をロードします。
        // 両方のシェーダーの読み込みが完了したら、メッシュを作成します。
        auto createCubeTask = (createPSTask && createVSTask).then([this] () {
            model[0] = new Load_Vertex(m_deviceResources);
            model[1] = new Load_Vertex(m_deviceResources);
            model[2] = new Load_Vertex(m_deviceResources);
            model[0]->Load("Dolphin1.x");
            model[1]->Load("Dolphin2.x");
            model[2]->Load("Dolphin3.x");
        });
    
        // メッシュが読み込まれたら、オブジェクトを描画する準備が完了します。
        createCubeTask.then([this] () {  m_loadingComplete = true;  });
    }
    
  4. Update() 関数では、時刻を m_totalRotation に保存して下さい。
    void Sample3DSceneRenderer::Update(DX::StepTimer const& timer)
    {
        if (!m_tracking)
        {
            // 度をラジアンに変換し、秒を回転角度に変換します
            float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
            m_totalRotation = timer.GetTotalSeconds() * radiansPerSecond;
            float radians = static_cast<float>(fmod(m_totalRotation, XM_2PI));
            Rotate(radians);
        }
    }
    
  5. Rotate() 関数では m_totalRotation を使って「0.0 ~ 4.0未満」のアニメーションを制御する chg を計算します。
    chg の整数値により、4通りの Blend() 関数を呼び出します。
    void Sample3DSceneRenderer::Rotate(float radians)
    {
        uint16  i;
        if (!m_loadingComplete) { return; }
        float chg = static_cast<float>(fmod(m_totalRotation, 4.0f));
        i = (uint16)chg;
        switch (i)
        {
            case 0: Blend(model[0], model[1], chg); break;
            case 1: Blend(model[1], model[2], chg); break;
            case 2: Blend(model[2], model[1], chg); break;
            case 3: Blend(model[1], model[0], chg); break;
        }
        XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(radians)));
    }
    
  6. Blend() 関数では *st と *end を wait の値でブレンドして頂点座標を計算します。
    ブレンドした頂点データで m_vertexBuffer と m_indexBuffer を設定します。
    //モデルのブレンド(wait: 0.0 ~ 3.9)
    void Sample3DSceneRenderer::Blend(Load_Vertex *st, Load_Vertex *end, float wait)
    {
        if (m_vertexBuffer!=nullptr)    m_vertexBuffer.Reset();
        if (m_indexBuffer!=nullptr)     m_indexBuffer.Reset();
        float w_e = static_cast<float>(fmod(wait, 1.0f));
        float w_s = 1.0f - w_e;
    
        unsigned    size = st->m_indexCount;
        VertexPosition  *vertex = new VertexPosition[size];
        for(unsigned i=0; i<size; i++)
        {   vertex[i].pos.x = (st->m_Vertex[i].pos.x*w_s) + (end->m_Vertex[i].pos.x*w_e);
            vertex[i].pos.y = (st->m_Vertex[i].pos.y*w_s) + (end->m_Vertex[i].pos.y*w_e);
            vertex[i].pos.z = (st->m_Vertex[i].pos.z*w_s) + (end->m_Vertex[i].pos.z*w_e);
            vertex[i].color = st->m_Vertex[i].color;
            vertex[i].norm = st->m_Vertex[i].norm;
        }
        CreateModel(vertex, st->m_Index, st->m_indexCount);
        if (vertex) delete vertex;
    }
    

[Previous Chapter ↑] Load_Vertex Class

超初心者のプログラム入門(DirectX Store)