Material Export

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

이번장에는 셰이딩 라이트, 디퓨즈, 엠비언트, 스펙큘러 칼라, 광택, 투명도와 같은 재질을 익스포트 해본다.
이러한 표준 재질에 접근하기 위해서는 StdMat 클래스가 필요하다.

바뀐 사항을 하나씩 알아 보자.

1. UI  추가

Export Material 체크 박스를 추가 하였다.  리소스 아이디는 IDC_CHECK_EXPORT_MATERIAL이다.

ExporterOption.h에 다음을 추가한다.

//ExporterOption.h

class ExporterOption

{

private:

    // Our options

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

    bool m_bExportMaterial;

 

public:

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

    bool ExportMaterial() { return m_bExportMaterial; }

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

};

체크박스에 대응하는 변수는 ExporterOption 클래스에 m_bExportMaterial을 추가하여 재질을 출력 할것인지 나타낸다. 속성 메쏘드도 같이 추가한다.

//ExporterOption.cpp

ExporterOption::ExporterOption()

{

    m_bExportObject = m_bExportAnimation = m_bExportMaterial = true;

    m_bForceSample = false;

}

 

 

INT_PTR CALLBACK ExporterOption::DialogProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

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

        case WM_INITDIALOG:

            SetCheckBox(hWnd, IDC_CHECK_EXPORT_MATERIAL, imp->ExportMaterial());

            return TRUE;

 

        case WM_COMMAND:

            switch(wParam)

            {

            case IDC_OK:

                imp->m_bExportMaterial = IsDlgButtonChecked(hWnd, IDC_CHECK_EXPORT_MATERIAL) == BST_CHECKED;

            }

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

}

m_bExportMaterial을 초기화 하고 WM_INITDIALOG 메시지에서 IDC_CHECK_EXPORT_MATERIAL 체크박스를 셋팅 한다.  익스포트시 OK 버튼을 누르면, ExportOption()클래스의 m_bExportMaterial 변수를 설정 한다.

2. 재질 익스포트( maxPluginTest.cpp )

//maxPluginTest.cpp

#include <stdmat.h>

 

class maxPluginTest : public SceneExport

{

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

    void ExportMaterial(INode* pNode, int iTreeDepth);

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

}

 

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

{

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

    // Write out the color information for this node.

    if (m_option.ExportMaterial())

        ExportMaterial(pNode, iTreeDepth);

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

}

 

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

{

    // The node stores the material for the object

    Mtl* pMtl = pNode->GetMtl();

    if (pMtl == NULL)

    {

        // This case is perfectly valid.  For simple scenes,

        // a node can specify a color for an object without

        // using the overhead of an entire material

        DWORD dwNodeColor = pNode->GetWireColor();

        Write(iTreeDepth, "Object Color: 0x%X", dwNodeColor);

    }

    else

    {

        // We have a material.  Lets export the basic parameters

        const MSTR& sMtlName = pMtl->GetName();

        Write(iTreeDepth, "Object Material: %s", sMtlName.data());

        WriteValue(iTreeDepth, "   Ambient: ", pMtl->GetAmbient());

        WriteValue(iTreeDepth, "   Diffuse: ", pMtl->GetDiffuse());

        WriteValue(iTreeDepth, "   Specular: ", pMtl->GetSpecular());

        WriteValue(iTreeDepth, "   Shininess: ", pMtl->GetShininess());

        WriteValue(iTreeDepth, "   Shininess Strength: ", pMtl->GetShinStr());

 

        if (pMtl->GetSelfIllumColorOn())

            WriteValue(iTreeDepth, "   Self Illumination: ", pMtl->GetSelfIllumColor());

        else

            WriteValue(iTreeDepth, "   Self Illumination: ", pMtl->GetSelfIllum());

 

        // We have written out the very basic properties for a material.

        // However, there are some more properties missing from this implementation

        // that we could use.  Here we test to see if we have the standard material

        // and export some of its more 'advanced' properties

        if (pMtl->IsSubClassOf(Class_ID(DMTL_CLASS_ID, 0)))

        {

            StdMat* pStdMtl = (StdMat*)pMtl;

            WriteValue(iTreeDepth, "   Opacity: ", pStdMtl->GetOpacity(0));

            WriteValue(iTreeDepth, "   Opacity Falloff: ", pStdMtl->GetOpacFalloff(0));

        }

    }

}

재질을 얻어올려면 stdmat 클래스가 필요하기 때문에 stdmat.h를 포함 시킨다.

Export Material 체크 박스가 체크 되어 있으면 재질을 익스포트 한다.

맥스에서는 노드당 하나의 재질이 있다. INode 클래스에서 노드의 재질에 접근하기 위해 제공되는 것은 GetMtl(), SetMtl() 메쏘드가 있다. GetMtl()은 Mtl 클래스의 인스턴스 포인터를 리턴한다.

NULL 값이 반환되면, 렌더링 속성을 위해 노드의 와이어 프레임 칼라를 사용한다.

SubClass가 ID가 DMTL_CLASS_ID면 스탠다드 매트리얼이다.
스탠다드 매트리얼은 어떤 sub-material도 가지고 있지 않다. 그렇지만 개발자가 접근하기 위해 필요로 하는 많은 파라메터를 가지고 있다.

     StdMat* pStdMtl = (StdMat*)pMtl

스탠다드 메트리얼로 변환 할려면 포인터로 캐스팅한다.

파라메터가 MULTI_CLASS_ID면 여러개의 서브 메트리얼을 가지고 있다는 것을 뜻한다.

멀티 서브 오브젝트는 기회가 되면 다루도록 하겠다.

결과)   8mtl.max      mtl.TXT

소스) maxPluginTest08_material.zip