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

导出整个网格,先不管材质等其他信息,结合以前的程序,下面是导出的主程序,这个主程序能导出一个没有后缀名的文件(加上后缀名.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打开后的结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值