UI Controls

Max Export 대화 상자를 추가한다.

추가 할 UI는 아래와 같이 체크박스 세개이다.
UI클래스는 ExporterOption으로 특별하게 어려움이 없을 것이다.

애니메이션을 익스포트 할 때, "Force Sample"이 체크 되면 Sample에 의해 익스포트 되고, 체크 되지 않으면, Key에 의해 익스포트 된다.

<리소스 ID>

대화 상자 :   IDD_OPTION
Export Object : IDC_CHECK_OBJECT
Export Animation : IDC_CHECK_ANIMATION
Force Sample :  IDC_CHECK_FORCE_SAMPLE
OK : IDC_OK
Cancel : IDC_CANCEL

maxPluginTest.cpp에서 ExporterOption을 어떻게 사용 하는지 보자.
 헤더 파일 ExporterOption.h를 추가하고 객체 m_option을 선언한다.

#include "ExporterOption.h"

 

......

 

class maxPluginTest : public SceneExport {

    ...........

    private:

        //Our options

        ExporterOption m_option;

        FILE* m_pFile;

기존 UI 콜백 함수 maxPluginTestOptionsDlgProc()는 제거하고 ExportererOption 클래스를 추가한다.
DoExport() 메쏘드 안에서 주석 처리되어 있던 대화 상자 생성 부분(DialogBoxParam)도 삭제한다.

int    maxPluginTest::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)

{

    //TODO: Implement the actual file Export here and

    //        return TRUE If the file is exported properly

/*

    if(!suppressPrompts)

        DialogBoxParam(hInstance,

                MAKEINTRESOURCE(IDD_PANEL),

                GetActiveWindow(),

                maxPluginTestOptionsDlgProc, (LPARAM)this);

*/

    ...........

}

 

대화 상자 m_option에 값에 의해 ExportAnimation(), ExportObject()를  익스포트 한다.

void maxPluginTest::Export(INode* pNode, int iTreeDepth /* = 0 */)

{

    ..............

    // Write out the animation (if it this node has any)

    if(m_option.ExportAnimation())

        ExportAnimation(pNode, iTreeDepth);

 

    // Write out this nodes object properties

    if(m_option.ExportObject())

        ExportObject(pNode, iTreeDepth);

    ...............

}

ExportAnimation()에서는 m_option.ForceSample()에 Sample이나 Key로 익스포트 할것인지 결정 한다.

void maxPluginTest::ExportAnimation(INode* pNode, int iTreeDepth)

{

    // How do we know this node is animated?

    // One way to tell is using validity intervals.

    // If the transform is valid forever, it never changes.

    Interval ivNodeValid = FOREVER;

    pNode->GetNodeTM(0, &ivNodeValid);

    if (ivNodeValid == FOREVER) return;

 

    // Has the user specified to sample

    // all animations?

    bool bSample = m_option.ForceSample();

 

    // Get the controller off the node.  If it is a TRS

    // see if we can export its keyframes

    Control* pNodeCtrl = pNode->GetTMController();

    Control* pSubCtrls[3];

    pSubCtrls[0] = pNodeCtrl->GetPositionController();

    pSubCtrls[1] = pNodeCtrl->GetRotationController();

    pSubCtrls[2] = pNodeCtrl->GetScaleController();

 

    // We should always prefer to export keyframes,

    // as it takes less space

    if (bSample != true)

    {

        for (int i = 0; i < 3; i++)

        {

            Control* pCtrl = pSubCtrls[i];

 

            // This is possible if we are not TRS

            // (eg, an IK Matrix3 controller)

            if (pCtrl != NULL)

            {

                // We always export keyframes if possible

                if (pCtrl->IsKeyable()) continue;

 

                if (pCtrl->GetXController() != NULL &&

                    pCtrl->GetYController() != NULL &&

                    pCtrl->GetZController() != NULL)

                {

                    // This control has XYZ dimensions -

                    // we understand this, we can export the

                    // subanim keyframes instead of the keyframes

                    // directly on the controller.  If we didnt

                    // have these dimensions, we couldnt assume

                    // how the sub-anims are used.

                    continue;

                }

            }

 

            // If we are here, we dont understand how one of the

            // TRS controllers derive its value.  In this case, we

            // have to sample the TRS to be sure we are correct

            bSample = true;

            break;

        }

    }

 

    if (bSample)

    {

        ExportAnimationSample(pNode, iTreeDepth);

    }

    else

    {

        Write(iTreeDepth, "TRS Export: ");

        ExportAnimationKeys(pSubCtrls[0], "Position", iTreeDepth + 1);

        ExportAnimationKeys(pSubCtrls[1], "Rotation", iTreeDepth + 1);

        ExportAnimationKeys(pSubCtrls[2], "Scale", iTreeDepth + 1);

    }

}

결과) key.TXT     sample.TXT

소스) maxPluginTest07_UI.zip