#include "mesh.h" namespace OgreMayaExporter { /***** Class Mesh *****/ // constructor Mesh::Mesh(const MString& name) { m_name = name; m_numTriangles = 0; m_pSkinCluster = NULL; m_pSkeleton = NULL; } // destructor Mesh::~Mesh() { clear(); } // clear data void Mesh::clear() { m_name = ""; m_numTriangles = 0; for (int i=0; i weights; std::vector jointIds; unsigned int numJoints = 0; std::vector vertices; MFloatPointArray points; MFloatVectorArray normals; vertices.resize(mesh.numVertices()); weights.resize(mesh.numVertices()); jointIds.resize(mesh.numVertices()); // get uv texture coordinate sets' names MStringArray uvsets; if (mesh.numUVSets() > 0) { stat = mesh.getUVSetNames(uvsets); if (MS::kSuccess != stat) { std::cout << "Error retrieving UV sets names\n"; return MS::kFailure; } } //Save uvsets info for (int i=m_uvsets.size(); inumOutputConnections(); for(unsigned int uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) { unsigned int uiIndex = m_pSkinCluster->indexForOutputConnection(uiGeometry); MObject kOutputObject = m_pSkinCluster->outputShapeAtIndex(uiIndex); if(kOutputObject == mesh.object()) { std:: cout << "Found skin cluster " << m_pSkinCluster->name().asChar() << " for mesh " << mesh.name().asChar() << "\n"; foundSkinCluster = true; } else { delete m_pSkinCluster; m_pSkinCluster = NULL; } } } // load connected skeleton (if present) if (m_pSkinCluster) { std::cout << "Loading skeleton data...\n"; if (!m_pSkeleton) m_pSkeleton = new Skeleton(); stat = m_pSkeleton->load(m_pSkinCluster,params); if (MS::kSuccess != stat) { std::cout << "Error loading skeleton data\n"; } else std::cout << "OK\n"; } } // get connected shaders MObjectArray shaders; MIntArray shaderPolygonMapping; stat = mesh.getConnectedShaders(0,shaders,shaderPolygonMapping); if (MS::kSuccess != stat) { std::cout << "Error getting connected shaders\n"; return MS::kFailure; } std::cout << "Found " << shaders.length() << " connected shaders\n"; if (shaders.length() <= 0) { std::cout << "No connected shaders, skipping mesh\n"; return MS::kFailure; } // create a series of arrays of faces for each different submesh std::vector polygonSets; polygonSets.resize(shaders.length()); // Get faces data // prepare vertex table for (int i=0; igetWeights(meshDag,component,vertexWeights,numJoints); weights[i]=vertexWeights; if (MS::kSuccess != stat) { std::cout << "Error retrieving vertex weights\n"; } // get ids for the joints if (m_pSkeleton) { MDagPathArray influenceObjs; m_pSkinCluster->influenceObjects(influenceObjs,&stat); if (MS::kSuccess != stat) { std::cout << "Error retrieving influence objects for given skin cluster\n"; } jointIds[i].setLength(weights[i].length()); for (int j=0; jgetJoints().size() && !foundJoint; k++) { if (influenceObjs[j].partialPathName() == m_pSkeleton->getJoints()[k].name) { foundJoint=true; jointIds[i][j] = m_pSkeleton->getJoints()[k].id; } } } } } } // create an iterator to go through mesh polygons if (mesh.numPolygons() > 0) { std::cout << "Iterate over mesh polygons\n"; MItMeshPolygon faceIter(mesh.object(),&stat); if (MS::kSuccess != stat) { std::cout << "Error accessing mesh polygons\n"; return MS::kFailure; } std::cout << "num polygons = " << mesh.numPolygons() << "\n"; // iterate over mesh polygons for (; !faceIter.isDone(); faceIter.next()) { int numTris=0; faceIter.numTriangles(numTris); // for every triangle composing current polygon extract triangle info for (int iTris=0; iTris 1) color.r = 1; if (color.g > 1) color.g = 1; if (color.b > 1) color.b = 1; if (color.a > 1) color.a = 1; } else { color = MColor(1,1,1,1); } if (vertices[vtxIdx].next == -2) // first time we encounter a vertex in this position { // save vertex position points[vtxIdx].cartesianize(); vertices[vtxIdx].pointIdx = vtxIdx; // save vertex normal vertices[vtxIdx].normalIdx = nrmIdx; // save vertex colour vertices[vtxIdx].r = color.r; vertices[vtxIdx].g = color.g; vertices[vtxIdx].b = color.b; vertices[vtxIdx].a = color.a; // save vertex texture coordinates vertices[vtxIdx].u.resize(uvsets.length()); vertices[vtxIdx].v.resize(uvsets.length()); // save vbas vertices[vtxIdx].vba.resize(weights[vtxIdx].length()); for (int j=0; j= 0) polygonSets[shaderPolygonMapping[faceIter.index()]].push_back(newFace); } // end iteration of triangles } } std::cout << "done reading mesh triangles\n"; // if we are using shared geometry, then create a list of vertices for the whole mesh if (params.useSharedGeom) { std::cout << "Create list of shared vertices\n"; for (i=0; i 0) { //create new submesh Submesh* pSubmesh = new Submesh(); //load linked shader stat = pSubmesh->loadMaterial(shaders[i],uvsets,params); if (stat != MS::kSuccess) { MFnDependencyNode shadingGroup(shaders[i]); std::cout << "Error loading submesh linked to shader " << shadingGroup.name().asChar() << "\n"; return MS::kFailure; } //load vertex and face data stat = pSubmesh->load(polygonSets[i],vertices,points,normals,uvsets,params,opposite); //add submesh to current mesh m_submeshes.push_back(pSubmesh); //update number of triangles composing the mesh m_numTriangles += pSubmesh->numTriangles(); } } return MS::kSuccess; } // Write mesh data to Ogre XML MStatus Mesh::writeXML(ParamList ¶ms) { MStatus stat; // start mesh description params.outMesh << "\n"; // write shared geometry (if used) if (params.useSharedGeom) { params.outMesh << "\t\n"; params.outMesh << "\t\t\n"; else params.outMesh << 0 << "\">\n"; // write vertex data for (int i=0; i < m_vertices.size(); i++) { params.outMesh << "\t\t\t\n"; //write vertex position params.outMesh << "\t\t\t\t\n"; //write vertex normal if (params.exportVertNorm) { params.outMesh << "\t\t\t\t\n"; } //write vertex colour if (params.exportVertCol) { float r,g,b,a; if (params.exportVertColWhite) { r = g = b = a = 1.0f; } else { r = m_vertices[i].r; g = m_vertices[i].g; b = m_vertices[i].b; a = m_vertices[i].a; } params.outMesh << "\t\t\t\t\n"; }//write vertex texture coordinates if (params.exportTexCoord) { for (int j=0; j\n"; } else { params.outMesh << "\t\t\t\t\n"; } } } params.outMesh << "\t\t\t\n"; } params.outMesh << "\t\t\n"; params.outMesh << "\t\n"; } // write submeshes data params.outMesh << "\t\n"; for (int i=0; i < m_submeshes.size(); i++) { stat = m_submeshes[i]->writeXML(params); if (MS::kSuccess != stat) { std::cout << "Error writing submesh " << m_submeshes[i]->name().asChar() << ", aborting operation\n"; return MS::kFailure; } } params.outMesh << "\t\n"; // write skeleton link if (params.exportSkeleton && m_pSkeleton) { int ri = params.skeletonFilename.rindex('\\'); int end = params.skeletonFilename.length() - 1; MString filename = params.skeletonFilename.substring(ri+1,end); if (filename.substring(filename.length()-4,filename.length()-1) == MString(".xml") && filename.length() >= 5) filename = filename.substring(0,filename.length()-5); params.outMesh << "\t\n"; } // Write shared geometry bone assignments if (params.useSharedGeom && params.exportVBA) { params.outMesh << "\t\n"; for (int i=0; i 0.001) { params.outMesh << "\t\t\n"; } } } params.outMesh << "\t\n"; } // write submesh names params.outMesh << "\t\n"; for (i=0; iname() != "") params.outMesh << "\t\tname().asChar() << "\" index=\"" << i << "\"/>\n"; } params.outMesh << "\t\n"; // end mesh description params.outMesh << "\n"; return MS::kSuccess; } }; //end of namespace