⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogremayamesh.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			MPlugArray srcPlugArray;
			ssPlug.connectedTo(srcPlugArray, true, false);
			
			if (srcPlugArray.length() > 0) {
				// This object contains a reference to a shader or material.
				// Check for known material types and extract material name.
				MObject srcNode = srcPlugArray[0].node();
				
				if (srcNode.hasFn(MFn::kPhong)) {
					MFnPhongShader fnPhong(srcNode);
					MaterialName = fnPhong.name();
                }
				else if (srcNode.hasFn(MFn::kLambert)) {
					MFnLambertShader fnLambert(srcNode);
					MaterialName = fnLambert.name();
				}
				else if (srcNode.hasFn(MFn::kBlinn)) {
					MFnBlinnShader fnBlinn(srcNode);
					MaterialName = fnBlinn.name();
				}
				else if (srcNode.hasFn(MFn::kReflect)) {
					MFnReflectShader fnReflect(srcNode);
					MaterialName = fnReflect.name();
				}
            }
		}


		// ===== Done
		return MaterialName;

	}

	//	--------------------------------------------------------------------------
	/**	Retrieve all Maya geometry for a single Maya mesh.
		\todo		Define materials if requested
		\todo		Fix normals
	*/	
	//	--------------------------------------------------------------------------
	MStatus MeshGenerator::_queryMayaGeometry(
        MFnMesh &fnMesh, 
		MeshMayaGeometry &rGeom
    ) {
        cout << "\nMeshGenerator::_queryMayaGeometry\n";

		MStatus status = MStatus::kSuccess;                

		// ===== Identification		
        rGeom.Name         = fnMesh.partialPathName(); // shortest unique name        
		rGeom.MaterialName = getMaterialName(fnMesh);        


		// ===== Geometry

		// --- Vertices
		status = fnMesh.getPoints(rGeom.Vertices, MSpace::kWorld);
		if (status == MStatus::kFailure) {
			cout << "\t[ERROR] MFnMesh::getPoints() failed\n"; 
			return status;
		}

        cout << "\tvertices count: " << rGeom.Vertices.length() << '\n';

		// --- Vertex normals
		status = fnMesh.getNormals(rGeom.FaceVertexNormals);
		if (status == MStatus::kFailure) {
			cout << "\t[ERROR] MFnMesh::getNormals() failed\n"; 
			return status;
		}

		// --- Triangular faces
		MDagPath dagPath;
		fnMesh.getPath(dagPath);
		MItMeshPolygon iterPoly(dagPath);
		
		int iPolygon, nPolygons;
		nPolygons = fnMesh.numPolygons();
		for (iPolygon=0; iPolygon < nPolygons; ++iPolygon)
		{
			MIntArray ThisPolyTriVertices;
			MPointArray ThisPolyPointsUntweaked;
			iterPoly.getTriangles(ThisPolyPointsUntweaked, ThisPolyTriVertices, MSpace::kWorld);

			_convertObjectToFace(iterPoly, ThisPolyTriVertices, rGeom.TriangleVertexIds);

			int iTriangle, nTriangles;
			iterPoly.numTriangles(nTriangles);
			for (iTriangle=0; iTriangle < nTriangles; ++iTriangle) {
				rGeom.TrianglePolygonIds.append(iPolygon);
			}

			iterPoly.next();
		}


		// ===== Colours and UVs

		// --- Face vertex colours
		status = fnMesh.getFaceVertexColors(rGeom.FaceVertexColours);
		if (status == MStatus::kFailure) {
			cout << "\t[ERROR] MFnMesh::getFaceVertexColors() failed\n"; 
			return status;
		}
		// Override non-existent colours with semi-transparent white
		unsigned int iFaceVertex;
		MColor mayaColour;
		for (iFaceVertex=0; iFaceVertex < rGeom.FaceVertexColours.length(); ++iFaceVertex) {
			mayaColour = rGeom.FaceVertexColours[iFaceVertex];
			if ((mayaColour.r) == -1) mayaColour.r = 1;
			if ((mayaColour.g) == -1) mayaColour.g = 1;
			if ((mayaColour.b) == -1) mayaColour.b = 1;
			if ((mayaColour.a) == -1) mayaColour.a = 0.2;
			rGeom.FaceVertexColours[iFaceVertex] = mayaColour;
		}

		// --- UV set names
		MStringArray UVSetNames;
		status = fnMesh.getUVSetNames(UVSetNames);
		if (status == MStatus::kFailure) {
			cout << "\t[ERROR] MFnMesh::getUVSetNames() failed\n"; 
			return status;
		}

		// --- Linked list of UV sets
		unsigned int nUVSets = UVSetNames.length();
		unsigned int iUVSet;

		// Loop over all UV sets
		MeshMayaUVSet UVSet;
		for (iUVSet = 0; iUVSet < nUVSets; ++iUVSet) {

			// Store UV name
			UVSet.sName = UVSetNames[iUVSet];

			// Retrieve UV coordinates
			status = fnMesh.getUVs(UVSet.uArray, UVSet.vArray, &(UVSet.sName));
			if (status == MStatus::kFailure) {
				return status;
			}

			// Store UV set
			rGeom.UVSets.push_back(UVSet);
		}


		// ===== Done
		return status;

	}


	//	--------------------------------------------------------------------------
	/** Parse Maya geometry into MeshGenerator format for further processing.
	*/	
	//	--------------------------------------------------------------------------
	MStatus MeshGenerator::_parseMayaGeometry(
        MFnMesh &fnMesh,
		MeshMayaGeometry &MayaGeometry, 
		MeshFaceVertexVector &FaceVertices, 
		MeshTriFaceList &TriFaces
    ) {
        cout << "\nMeshGenerator::_parseMayaGeometry\n";

		MStatus status;

		// --- Determine number of triangles
		unsigned int nTris = MayaGeometry.TrianglePolygonIds.length();
		if (nTris == 0) {
			return MStatus::kFailure;
		}

		// --- Confirm number of triangle vertices
		unsigned int nTriVertices = MayaGeometry.TriangleVertexIds.length();
		if (nTriVertices != 3*nTris) {
			cout << "\t[ERROR] "<<nTris<<" triangles require "<<(3*nTris)<<" vertices but "<<nTriVertices<<" vertices present!\n";
			return MStatus::kFailure;
		}

		// --- Loop over all triangles
		unsigned int iTri;
		cout << "\texporting "<<fnMesh.numPolygons()<<" faces as "<<nTris<<" triangles from "<<MayaGeometry.Name.asChar()<<" (material "<<MayaGeometry.MaterialName.asChar()<<")...\n";

		for (iTri = 0; iTri < nTris; ++iTri) {

			// --- Get polygon index
			unsigned int iPoly;
			iPoly = MayaGeometry.TrianglePolygonIds[iTri];

			// --- Get indices of face-vertices
			MIntArray VertexIds;
			status = fnMesh.getPolygonVertices(iPoly, VertexIds);
			if (status == MStatus::kFailure) {
				MGlobal::displayError("MFnMesh::getPolygonVertices()");
				return status;
			}

			// --- Get indices of face-vertex normals
			MIntArray NormalIds;
			/*if (OPTIONS.exportNormals)*/ {
				fnMesh.getFaceNormalIds(iPoly, NormalIds);
				if (status == MStatus::kFailure) {
					MGlobal::displayError("MFnMesh::getFaceNormalIds()");
					return status;
				}
			}

			// --- Loop over all face-vertices
			unsigned int iTriVertex;
            MeshFaceVertex faceVertices[3];
			for (iTriVertex = 0; iTriVertex < 3; ++iTriVertex) {
				
				MeshFaceVertex& FaceVertex = faceVertices[iTriVertex];

				// Get polygon vertex id
				unsigned int iPolyVertex;
				iPolyVertex = MayaGeometry.TriangleVertexIds[3*iTri + iTriVertex];

				// Lookup and store face-vertex position
				MPoint mayaPoint;
				int iVertex = VertexIds[iPolyVertex];
				mayaPoint = MayaGeometry.Vertices[iVertex];
                
                MFloatArray* weights = 0;

                if(iVertex < MayaGeometry.Weights.size()) {
                    weights = &MayaGeometry.Weights[iVertex];
                }

				FaceVertex.vecPosition.x = mayaPoint.x;
				FaceVertex.vecPosition.y = mayaPoint.y;
				FaceVertex.vecPosition.z = mayaPoint.z;

				// Lookup and store face-vertex normal
				/*if (OPTIONS.exportNormals)*/ {
					MVector mayaNormal;
					int iNormal = NormalIds[iPolyVertex];
					mayaNormal = MayaGeometry.FaceVertexNormals[iNormal];
					FaceVertex.vecNormal.x = mayaNormal.x;
					FaceVertex.vecNormal.y = mayaNormal.y;
					FaceVertex.vecNormal.z = mayaNormal.z;
				}

				// Lookup and store face-vertex colour
				/*if (OPTIONS.exportColours)*/ {
					int iColour;
					MColor mayaColour;
					status = fnMesh.getFaceVertexColorIndex(iPoly, iPolyVertex, iColour);
					mayaColour = MayaGeometry.FaceVertexColours[iColour];
					FaceVertex.colour.r = mayaColour.r;
					FaceVertex.colour.g = mayaColour.g;
					FaceVertex.colour.b = mayaColour.b;
					FaceVertex.colour.a = mayaColour.a;
				}

				// Loop over UV sets
				/*if (OPTIONS.exportUVs)*/ {
					MeshMayaUVSetList::iterator iterUVSet;
					iterUVSet = MayaGeometry.UVSets.begin();
					while (iterUVSet != MayaGeometry.UVSets.end()) {                        
						int iUV;
						MStatus stat = fnMesh.getPolygonUVid(iPoly, iPolyVertex, iUV, &(iterUVSet->sName));
					
						MeshVertexUV VertexUV;
                        if(!stat.error()) {						    
						    VertexUV.u = iterUVSet->uArray[iUV];
						    VertexUV.v = 1.0f - iterUVSet->vArray[iUV];	// CJV 2004-01-05: Required for Ogre 0.13
		                }
						else {
							VertexUV.u = 0;
							VertexUV.v = 0;
						}

						FaceVertex.listUV.push_back(VertexUV);
						
                        ++iterUVSet;                        
					}
				}

                // assign weights
                if(weights) {
                    const float eps = 0.001f;
                    float acc;                    

                    for(int i=weights->length()-1; i>=0; i--) {
                        acc = 0;
                        if((*weights)[i] < eps) {
                            acc += (*weights)[i];
                        }
                        else {
                            VertexBoneAssigment vba;

                            vba.boneId   = i;                            
                            vba.weight   = (*weights)[i];// + (acc/(float)i);

                            FaceVertex.boneAssigments.push_front(vba);
                        }
                    }                    
                }
			}


            
            // OPTIMIZIATION CODE: BEGIN
            // Search in the current vertex vector for occurance           
            int index[3];
            for(int i=0; i<3; i++) {
                
                vector<MeshFaceVertex>::iterator it;
                vector<MeshFaceVertex>::iterator end = FaceVertices.end();
                
                int j;
                for(j=0, it=FaceVertices.begin(); it!=end; ++it, j++) {
                    if(faceVertices[i] == *it) {
                        // this vertex is already in vector -> reuse
                        index[i] = j;
                        break;
                    }
                }

                // if can not be found in vector, insert
                if(it==end) {
                    index[i] = FaceVertices.size();
                    FaceVertices.push_back(faceVertices[i]);
                }
            }
            // OPTIMIZIATION CODE: END
            

			// --- Define face (three face-vertices)
			MeshTriFace TriFace;
			TriFace.index0 = (unsigned long)index[0];
			TriFace.index1 = (unsigned long)index[1];
			TriFace.index2 = (unsigned long)index[2];

			TriFaces.push_back(TriFace);
		}

		return MStatus::kSuccess;
	}
    

	//	--------------------------------------------------------------------------
	/** Determines if a given DAG node is currently visible.
		\param		fnDag
					DAG node to check
		\param		status
					Status code from Maya API

		\return		True if node is visible, False if node is not visible or if
					unable to determine visibility
	*/	
	//	--------------------------------------------------------------------------
	bool MeshGenerator::_isVisible(MFnDagNode &fnDag, MStatus &status) {		        

        if(fnDag.isIntermediateObject()) {
			return false;
		}

		bool bVisible = false;
		MPlug visPlug = fnDag.findPlug("visibility", &status);
		if (MStatus::kFailure == status) {
			cout << "[WARNING] can not find \"visibility\" plug, returning false\n";
		} else {
			status = visPlug.getValue(bVisible);
			if (MStatus::kFailure == status) {
				bVisible = false;
                cout << "[WARNING] can not query \"visibility\" plug, returning false\n";
			}
		}

		return bVisible;
	}


	//	--------------------------------------------------------------------------
	/** Convert an array of object-relative vertex indices into an array of face-
		relative vertex indices. Required because MItMeshPolygon::getTriangle()
		returns object-relative vertex indices, whereas many other methods require
		face-relative vertex indices.

		Adapted from "How do I write a polygon mesh exporter?" at URL 
		http://www.ewertb.com/maya/api/api_a18.html.

		\param		iterPoly
					Reference to a polygon iterator that is currently at the 
					polygon of interest
		\param		objIndices
					Reference to array of object-relative indices
		\param		faceIndices
					Reference to array of face-relative indices (output). Indices
					are appended to the end of this array. A value of -1 will be 
					appended if there is no corresponding vertex.
	*/	
	//	--------------------------------------------------------------------------
	void MeshGenerator::_convertObjectToFace(
        MItMeshPolygon &iterPoly, 
		MIntArray &objIndices, 
		MIntArray &faceIndices
    ) {
		MIntArray polyIndices;
		iterPoly.getVertices(polyIndices);
			
		bool bMatched;
		unsigned int iPoly, iObj;
		for (iObj=0; iObj < objIndices.length(); ++iObj)
		{
			bMatched = false;
			
			// iPoly is face-relative vertex index
			for (iPoly=0; iPoly < polyIndices.length(); ++iPoly)
			{
				if (objIndices[iObj] == polyIndices[iPoly]) {
					faceIndices.append(iPoly);
					bMatched = true;
					break;
				}

			}

			// default if no match found
			if (!bMatched) {
				faceIndices.append(-1);
			}

		}
	}
	

} // namespace OgreMaya

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -