您的位置:首页 > 编程语言

3DS Max plugin 编程八,导出单个物体

2011-11-30 20:28 155 查看
导出整个网格,先不管材质等其他信息,结合以前的程序,下面是导出的主程序,这个主程序能导出一个没有后缀名的文件(加上后缀名.mesh就能被ogre meshy识别)。该文件用ogre meshy打开后,能显示出3DS Max中的一个mesh。

int	OgreMaxExport::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)
{
m_pMaxScene = GetIGameInterface();

IGameConversionManager *pConMan = GetConversionManager();
pConMan->SetCoordSystem (IGameConversionManager::IGAME_OGL);

m_pMaxScene->SetPropertyFile("IGameProp.xml");
m_pMaxScene->InitialiseIGame(false);

m_iNodeCount = m_pMaxScene->GetTopLevelNodeCount();

if (m_iNodeCount == 0)
{
MessageBox (NULL, "No node in current scene", "Max plug-in", MB_OK);
return 0;
}

//////////////////////////////////////////////////////////////////////////
IGameNode* pNode = m_pMaxScene->GetTopLevelNode(0);

IGameObject* pObject = pNode->GetIGameObject();
IGameObject::ObjectTypes type = pObject->GetIGameType();
IGameMaterial* mtl = pNode->GetNodeMaterial();

int iFaceCount, iVertexCount;

if (type == IGameObject::IGAME_MESH)
{
IGameMesh* pMesh = (IGameMesh*) pObject;
if (!pMesh->IsEntitySupported())
{
MessageBox (NULL, "Entity not supported", "Max plug-in", MB_OK);
return 0;
}

if (!pMesh->InitializeData())
{
MessageBox (NULL, "Mesh InitializeData() failed!", "Max plug-in", MB_OK);
return 0;
}

iVertexCount   = pMesh->GetNumberOfVerts();
iFaceCount     = pMesh->GetNumberOfFaces();

Tab<int> texMap = pMesh->GetActiveMapChannelNum();

TiXmlDocument *pXmlDoc = new TiXmlDocument();

char stub[128];

TiXmlDeclaration* declarationElem = new TiXmlDeclaration(_T("1.0"), _T(""), _T(""));
pXmlDoc->LinkEndChild(declarationElem);

TiXmlElement* meshElem = new TiXmlElement("mesh");
pXmlDoc->LinkEndChild(meshElem);

// <submeshes> </submeshes>
TiXmlElement* submeshes = new TiXmlElement("submeshes");
meshElem->LinkEndChild(submeshes);

// <submesh> </submesh>
TiXmlElement* submesh = new TiXmlElement("submesh");
submeshes->LinkEndChild(submesh);

if (mtl != NULL)
submesh->SetAttribute("material", mtl->GetMaterialName());
else
submesh->SetAttribute("material", "");
submesh->SetAttribute("usesharedvertices", "false");
submesh->SetAttribute("use32bitindexes", 0);

// <faces> </faces>
TiXmlElement* faces = new TiXmlElement("faces");
submesh->LinkEndChild(faces);

faces->SetAttribute("count", iFaceCount);

int index = 0;

for (index = 0; index < iFaceCount; index++)
{
TiXmlElement* face = new TiXmlElement("face");
faces->LinkEndChild(face);

FaceEx* pFace = pMesh->GetFace(index);

for (int i = 0; i < 3; i++)
{
// vertex
Point3 vertex = pMesh->GetVertex(pFace->vert[i]);
m_vertexVector.push_back(vertex);

// vertex color (diffuse)
Point3 diffuse = pMesh->GetColorVertex(pFace->vert[i]);
float alpha = pMesh->GetAlphaVertex(pFace->vert[i]);

m_diffuseVector.push_back(diffuse);
m_alphaVector.push_back(alpha);

Point3 normal = pMesh->GetNormal(pFace, i);
m_normalVector.push_back(normal);

DWORD idx[3];
Point3 tv;
for (int ch = 0; ch < texMap.Count(); ch++)
{

if (pMesh->GetMapFaceIndex(texMap[ch], index, idx))
tv = pMesh->GetMapVertex(texMap[ch], idx[i]);
else
tv = pMesh->GetMapVertex(texMap[ch], pFace->vert[i]);

m_tvMap.insert(pair<int, Point3>(texMap[ch], tv));
}

memset(stub, 0, 128);
sprintf (stub, "v%d", i+1);
face->SetAttribute(stub, m_vertexVector.size() - 1);
}
}

TiXmlElement* geometry = new TiXmlElement("geometry");
submesh->LinkEndChild(geometry);

geometry->SetAttribute("vertexcount", iVertexCount);

TiXmlElement* vertexbuffer = new TiXmlElement("vertexbuffer");
geometry->LinkEndChild(vertexbuffer);

vertexbuffer->SetAttribute("positions", "true");
vertexbuffer->SetAttribute("normals", "false");
vertexbuffer->SetAttribute("colours_diffuse", "false");
vertexbuffer->SetAttribute("texture_coords", texMap.Count());

for (index = 0; index < texMap.Count(); index++)
{
memset(stub, 0, 128);
sprintf(stub, "texture_coords_dimension_%d", index);
vertexbuffer->SetAttribute(stub, "2");
}

std::vector<Point3>::size_type ii = m_vertexVector.size();
for (ii = 0; ii < m_vertexVector.size(); ii++)
{
TiXmlElement* vertex = new TiXmlElement("vertex");
vertexbuffer->LinkEndChild(vertex);

// position
TiXmlElement* position = new TiXmlElement("position");
vertex->LinkEndChild(position);

Point3 pos = (Point3) m_vertexVector.at(ii);

position->SetDoubleAttribute("x", pos.x);
position->SetDoubleAttribute("y", pos.y);
position->SetDoubleAttribute("z", pos.z);

// vertex color (diffuse)
TiXmlElement* colour_diffuse = new TiXmlElement("colour_diffuse");
vertex->LinkEndChild(colour_diffuse);

Point3 diffuse = m_diffuseVector.at(ii);
memset(stub, 0, 128);
sprintf(stub, "    %f    %f    %f", diffuse.x, diffuse.y, diffuse.z);
colour_diffuse->SetAttribute("value", stub);

// vertex normal
TiXmlElement* normal = new TiXmlElement("normal");
vertex->LinkEndChild(normal);

Point3 vertexNormal = m_normalVector.at(ii);
normal->SetDoubleAttribute("x", vertexNormal.x);
normal->SetDoubleAttribute("y", vertexNormal.y);
normal->SetDoubleAttribute("z", vertexNormal.z);

}

pXmlDoc->SaveFile(name);
delete pXmlDoc;
}

return 1;
}


需要注意的地方是:

1、C++的new的操作符在堆上创建相关对象,一般我们显式创建的对象,需要我们自己显式调用delete个来删除。但是用TinyXML的时候,这部分东西是TinyXML自己管理的,所以不用自己用delete,否则会出错;

2、ogre的顶点格式导出的时候,下标从1开始,不是0;否则会出错。这是我们这句代码的原因:

sprintf (stub, "v%d", i+1);


最后,这个是导出的茶壶的mesh用ogre meshy打开后的结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息