XML Exporter: Material Export

맥스에서 재질과 다이렉트 X의 재질의 개념은 다르다. 맥스에서 재질은 하나의 메쉬당 여러개의 재질을 가질수 있다. DX에서는 재질과 텍스쳐가 분리 되어 있지만 맥스에서는 재질에 텍스쳐가 포함 된다.

맥스의 재질을 게임에서 그대로 구현했다간 혈압 상승과 게임 최적화를 감당할 수 없기 때문에 디퓨즈 맵만 익스포트 하도록 한다.

실행 순서:  BuildMaterial() --> CollectMaterial() --> WriteMaterial()
간단하게 요약하면 다음과 같다.

Export 메인함수에서 부르는 함수로 XmlExp를 자식까지 재귀 호출 한다.

m_pINode->GetMtl() 메트리얼이 있으면 CollectMaterial()을 실행한다.

void XmlExp::BuildMaterial()

 

pMtl->NumSubTexmaps() 메트리얼의 서브 텍스쳐가 있고 디퓨즈 맵이면 WriteMaterial()을 실행

void XmlExp::CollectMaterial( INode* pNode, Mtl* pMtl )

 

디퓨즈 맵(ID_DI)이면 텍스쳐 이름과 재질을 저장

void XmlExp::WriteMaterial( Mtl* pMtl, Texmap* texMap, int nSubID )

 

BuildMaterial

INode::GetMtl() : 메트리얼(Mtl)을 리턴한다.

void XmlExp::BuildMaterial()

{

    if( m_pINode )

    {

        Mtl* pMtl = m_pINode->GetMtl();

        CollectMaterial( m_pINode, pMtl );

    }

 

    .......

    재귀 호출: BuildMaterial()

}

 

CollectMaterial

Mtl::NumSubTexmaps() : 텍스쳐의 갯수를 구한다.
Mtl::GetSubTexmap() : Texmap을 리턴한다.
Mtl::NumSubMtls() : 서브 재질의 갯수를 구한다.
Mtl::GetSubMtl() : 서브 재질 Mtl을 리턴한다.

맥스에서 재질은 INode 처럼 트리구조로 되어 있다. 그래서 GetSubMtl()로 계속 순회하면서 디퓨즈 맵을 검색한다.

void XmlExp::CollectMaterial( INode* pNode, Mtl* pMtl )

{

    if( pMtl == NULL )

        return;

 

    int nSub = pMtl->NumSubTexmaps();

 

    for( int n=0; n<nSub; ++n )

    {

        Texmap* subTexMap = pMtl->GetSubTexmap(n);

        if( subTexMap == NULL )

            continue;

 

        WriteMaterial( pMtl, subTexMap, n );

    }

 

    int iSub = pMtl->NumSubMtls();

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

    {

        Mtl* pSubMtl = pMtl->GetSubMtl(i);

        CollectMaterial( m_pINode, pSubMtl );

    }           

}

 

WriteMaterial

텍스쳐맵의 ID가 Class_ID(BMTEX_CLASS_ID, 0x0)이면 이미지 파일이다.
SubTexmap의 ID가 ID_DI이면 디퓨즈 맵으로 이때 텍스쳐 이름과 재질의 Ambient, Diffuse, Specular 값을 저장한다.

void XmlExp::WriteMaterial( Mtl* pMtl, Texmap* texMap, int nSubID )

{

    if (texMap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x0))

    {

        //경로를 포함한 경로

        TSTR bitmapFile = ((BitmapTex *)texMap)->GetMapName();

        if( bitmapFile.data() && strlen(bitmapFile) > 3 )

        {

            TSTR className;

            texMap->GetClassName(className);

 

            TSTR fileName;

            SplitPathFile(bitmapFile, NULL, &fileName);

 

            if(ID_DI == nSubID)    // diffuse Map

            {

                XmlExp* meshXmlExp = (XmlExp*)this->FindFirstChild( "mesh" );

                if( meshXmlExp )

                {

                    //텍스쳐 이름 저장, bitmapFile이나 fileName을 저장

                    Color c = pMtl->GetAmbient();

                    c = pMtl->GetDiffuse(); 

                    c = pMtl->GetSpecular();

                    ........

                }

            }

        }

    }

}

 

프로젝트 : maxProject_material.zip