3DS Max plugin 编程八,导出单个物体
2011-11-30 20:28
155 查看
导出整个网格,先不管材质等其他信息,结合以前的程序,下面是导出的主程序,这个主程序能导出一个没有后缀名的文件(加上后缀名.mesh就能被ogre meshy识别)。该文件用ogre meshy打开后,能显示出3DS Max中的一个mesh。
需要注意的地方是:
1、C++的new的操作符在堆上创建相关对象,一般我们显式创建的对象,需要我们自己显式调用delete个来删除。但是用TinyXML的时候,这部分东西是TinyXML自己管理的,所以不用自己用delete,否则会出错;
2、ogre的顶点格式导出的时候,下标从1开始,不是0;否则会出错。这是我们这句代码的原因:
最后,这个是导出的茶壶的mesh用ogre meshy打开后的结果:
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打开后的结果:
![](http://hi.csdn.net/attachment/201112/1/0_1322746111Qp76.gif)
相关文章推荐
- 3DS Max plugin 编程三,utility
- 3DS Max plugin 编程四,配置Hybrid
- 3DS Max plugin 编程六,使用上SDK的库
- 3DS Max plugin 编程七,简单了解Ogre的XML格式内容(DTD)
- 3DS Max Plugin 编程一,开始
- 3DS Max Plugin 编程二,CryEngine的Max插件安装
- 3DS Max plugin 编程五,第一行代码
- 3DS文件导出MultiPatch
- 3ds Max导出OBJ的mtl贴图路径不正确
- 万圣节福利:红孩儿3D引擎开发课程《3ds max导出插件初步》
- 面向组件编程之Unity 4.怎样得到游戏场景中的对象 例如:layer/tag&&SetActive隐藏游戏物体
- idea中将单个java类导出为jar包文件的方法
- VS2015动态库编程之导出C++类(上)
- 3DS MAX PlugIn 材质和纹理
- 面向组件编程之Unity 11.Quaternion类属性 线性插值Lerp() 关键字:按键控制游戏物体朝向
- 向量几何在游戏编程中的使用【5】物体的旋转
- 深入浅出Dll(介绍函数导出、类导出、钓子dll、不同语言混合编程方法、插件等的实现方法)
- 3DS导出到Unity3D的注意事项
- 3ds max sdk导出插件编写心得
- 搜狗浏览器导出单个收藏夹