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

📄 ogremayamesh.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
============================================================================
This source file is part of the Ogre-Maya Tools.
Distributed as part of Ogre (Object-oriented Graphics Rendering Engine).
Copyright (C) 2003 Fifty1 Software Inc., Bytelords

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
or go to http://www.gnu.org/licenses/gpl.txt
============================================================================
*/
#include "OgreMayaMesh.h"
#include "OgreMayaOptions.h"

#include <maya/MItGeometry.h>
#include <maya/MFnMesh.h>
#include <maya/MDagPath.h>
#include <maya/MDagPathArray.h>
#include <maya/MSelectionList.h>
#include <maya/MGlobal.h>
#include <maya/MPlug.h>
#include <maya/MFnLambertShader.h>
#include <maya/MFnBlinnShader.h>
#include <maya/MFnPhongShader.h>
#include <maya/MFnReflectShader.h>
#include <maya/MFnSet.h>
#include <maya/MPlugArray.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MItDag.h>

#include <maya/MItDependencyNodes.h>
#include <maya/MFnSkinCluster.h>

#include <iostream>
#include <string>

#include <math.h>

namespace OgreMaya {

    using namespace std;

	//	--------------------------------------------------------------------------
	/** Standard constructor. Creates Ogre Mesh and defines known options.
	*/	
	//	--------------------------------------------------------------------------
	MeshGenerator::MeshGenerator() {
	}


	//	--------------------------------------------------------------------------
	/** Destructor.
	*/	
	//	--------------------------------------------------------------------------
	MeshGenerator::~MeshGenerator()
	{
	}


	//	--------------------------------------------------------------------------
	/** Finds and exports all polygonal meshes in the DAG. Each polygonal mesh
		corresponds to a single Ogre SubMesh.

		\return		True if exported ok, false otherwise
	*/	
	//	--------------------------------------------------------------------------
	bool MeshGenerator::exportAll()
	{
		MStatus status;
		bool bStatus = true;        

		// ===== Iterate over mesh components of DAG

		// --- Setup iterator
		MItDag iterDag(MItDag::kDepthFirst, MFn::kMesh, &status);
		if (status == MStatus::kFailure) {
			MGlobal::displayError("MItDag::MItDag");
			return false;
		}


        {
            ofstream out(OPTIONS.outMeshFile.c_str());

            out.precision(5);
            out.setf(ios::fixed);
        
            out << "<mesh>\n";
            out << "\t<submeshes>\n";

			MSelectionList list;
			MGlobal::getActiveSelectionList(list);

		    // --- Iterate
		    for(; !iterDag.isDone(); iterDag.next()) {
		    
			    // Get DAG path
			    MDagPath dagPath;
			    status = iterDag.getPath(dagPath);
			    if (status == MStatus::kFailure) {
				    MGlobal::displayError("MDagPath::getPath");
				    bStatus = false;
				    break;
			    }

			    // Process this node?
				//if(OPTIONS.exportSelected && !list.hasItem(dagPath.node())) continue;
			    
				if( dagPath.hasFn(MFn::kTransform)) continue;
			    if(!dagPath.hasFn(MFn::kMesh))      continue;
			    
				MFnDagNode dagNode(dagPath);
			    if(dagNode.isIntermediateObject())  continue;

			    // Process node if visible
			    bool bVisible;
			    bVisible = _isVisible(dagNode, status);
			    if (bVisible && (status == MStatus::kSuccess)) {
				    status = _processPolyMesh(out, dagPath);
				    if (status != MStatus::kSuccess) {
					    break;
				    }
			    }
		    }

            out << "\t</submeshes>\n";
            
            if(OPTIONS.exportSkeleton || OPTIONS.exportVBA) {
                string skeletonName =
                    OPTIONS.outSkelFile.substr(
                        0, OPTIONS.outSkelFile.find_last_of('.')
                    );
                out << "\t<skeletonlink name=\""<<skeletonName<<"\"/>\n";
            }

            out << "</mesh>\n";
        }

		// reactivate IK Solver
		MGlobal::executeCommand("ikSystem -e -sol 1;");

		// ===== Done
		return (status == MStatus::kSuccess);
	}


	//	--------------------------------------------------------------------------
	/**	Process a Maya polyMesh to generate an Ogre SubMesh.

		\param		dagPath
					Path to the Maya polyMesh to be processed

		\return		MStatus::kSuccess if processed successfuly, 
					different MStatus otherwise

		\todo		Vertex optimization
		\todo		Submesh optimization (merge submeshes that share materials)
	*/	
	//	--------------------------------------------------------------------------
	MStatus MeshGenerator::_processPolyMesh(ofstream& out, const MDagPath dagPath) {		        

        cout << "\nMeshGenerator::_processPolyMesh\n";
        cout << "\tdagPath = \"" << dagPath.fullPathName().asChar() << "\"\n";       

        MStatus status = MStatus::kSuccess;
        MeshMayaGeometry MayaGeometry;

//*******************************************************************
        
        // ===== Calculate the influence of SkinCluter if any
        bool hasSkinCluster = false;                                    
            
	    //search the skin cluster affecting this geometry
	    MItDependencyNodes kDepNodeIt( MFn::kSkinClusterFilter );            

        MFnMesh fnMesh(dagPath, &status);

	    for( ;!kDepNodeIt.isDone() && !hasSkinCluster; kDepNodeIt.next()) {            

            MObject	kInputObject, kOutputObject;                    
		    MObject kObject = kDepNodeIt.item();

		    MFnSkinCluster kSkinClusterFn(kObject, &status);

            cout << "\tskin cluster name: " << kSkinClusterFn.name().asChar() << '\n';


            unsigned int uiNumGeometries = kSkinClusterFn.numOutputConnections();

            cout << "\tfound " << uiNumGeometries << " geometry object(s) in skin cluster\n";

            for(unsigned int uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) {
	            unsigned int uiIndex = kSkinClusterFn.indexForOutputConnection( uiGeometry, &status );


	            kInputObject = kSkinClusterFn.inputShapeAtIndex( uiIndex, &status );
	            kOutputObject = kSkinClusterFn.outputShapeAtIndex( uiIndex, &status );

                if(kOutputObject == fnMesh.object()) {
                    cout << "\tgeometry located in skin cluster\n";
                    hasSkinCluster = true;

/*                    
                    MDagPathArray jointPaths;
                    kSkinClusterFn.influenceObjects(jointPaths, &status);
                    int dummy;
	                string rootName = jointPaths[0].partialPathName(&status).asChar();

           	        MGlobal::executeCommand("ikSystem -e -sol 0;");
	                MGlobal::selectByName(rootName.c_str());
	                MGlobal::executeCommand("dagPose -r -g -bp");
*/

                    // get weights
                    MItGeometry kGeometryIt(kInputObject);
			        for(int uiVertex = 0; !kGeometryIt.isDone(); kGeometryIt.next(), ++uiVertex ) {
				        MObject kComponent = kGeometryIt.component( 0 );

				        MFloatArray kWeightArray;
				        unsigned int uiNumInfluences;

				        kSkinClusterFn.getWeights(dagPath, kComponent, kWeightArray, uiNumInfluences);
                                    
                        MayaGeometry.Weights.push_back(kWeightArray);
                    }
                }
            }
        
        }           
                          
        
        // ===== Get Maya geometry		
		status = _queryMayaGeometry(fnMesh, MayaGeometry);
		if (status == MStatus::kFailure) {
			return status;
		}

/*
        if(hasSkinCluster) {	
	        MGlobal::executeCommand("ikSystem -e -sol 1;");
        }
*/

		// ===== Parse into MeshGenerator format
		MeshFaceVertexVector FaceVertices;
		MeshTriFaceList      TriFaces;
		status = _parseMayaGeometry(fnMesh, MayaGeometry, FaceVertices, TriFaces);
		if (status == MStatus::kFailure) {
			return status;
		}


////////////////////////////////////////////////////////////////////////////////
                
        // export as XML
        out << "\t\t<submesh material=\"" << OPTIONS.matPrefix << MayaGeometry.MaterialName.asChar() << "\" usesharedvertices=\"false\" use32bitindexes=\"false\">\n";    
	

		// ===== Create Ogre face list
		// --- Basic info
		unsigned int nTriFaces = (unsigned int)TriFaces.size();
		// --- Store face indices
		MeshTriFaceList::iterator faceIt, faceEnd;
        faceEnd = TriFaces.end();

        out << "\t\t\t<faces count=\"" << nTriFaces << "\">\n";
        for(faceIt=TriFaces.begin(); faceIt!=faceEnd; ++faceIt) {
            out << "\t\t\t\t<face ";
			out << "v1=\"" << faceIt->index0 << "\" ";
			out << "v2=\"" << faceIt->index1 << "\" ";
			out << "v3=\"" << faceIt->index2 << "\"/>\n";
		}
        out << "\t\t\t</faces>\n";



        out << "\t\t\t<geometry vertexcount=\"" << FaceVertices.size() << "\">\n";
        

		MeshFaceVertexVector::iterator vertexIt, vertexEnd;
        vertexEnd = FaceVertices.end();

        //
        // POSITIONS
        //
        out << "\t\t\t\t<vertexbuffer ";
        out << "positions=\"true\"";	    
        if(OPTIONS.exportNormals)
            out << " normals=\"true\"";
        if(OPTIONS.exportColours)
            out << " colours_diffuse=\"true\"";
        if(MayaGeometry.UVSets.size() > 0 && OPTIONS.exportUVs)          
            out << " texture_coords=\"" << MayaGeometry.UVSets.size() << "\"";
        out << ">\n";
        
        
		for(vertexIt=FaceVertices.begin(); vertexIt!=vertexEnd; ++vertexIt)	{            
            out << "\t\t\t\t\t<vertex>\n";
            
            out << "\t\t\t\t\t\t<position ";
            out << "x=\"" << vertexIt->vecPosition.x << "\" ";
			out << "y=\"" << vertexIt->vecPosition.y << "\" ";
			out << "z=\"" << vertexIt->vecPosition.z << "\"/>\n";

            if(OPTIONS.exportNormals) {
                out << "\t\t\t\t\t\t<normal ";
                out << "x=\"" << vertexIt->vecNormal.x << "\" ";
			    out << "y=\"" << vertexIt->vecNormal.y << "\" ";
                out << "z=\"" << vertexIt->vecNormal.z << "\"/>\n";
            }


            if(OPTIONS.exportColours) {            
                out << "\t\t\t\t\t\t<colour_diffuse value=\"";
                out << vertexIt->colour.r << " ";
			    out << vertexIt->colour.g << " ";
                out << vertexIt->colour.b << " ";
			    out << vertexIt->colour.a << "\"/>\n";                
		    }

            if(MayaGeometry.UVSets.size() > 0 && OPTIONS.exportUVs) {
                MeshVertexUVList::iterator uvIt, uvEnd;
			    uvEnd = vertexIt->listUV.end();
			    for (uvIt = vertexIt->listUV.begin(); uvIt!=uvEnd; ++uvIt) {                    

                    float u,v;
                    u = uvIt->u;
                    //v = 1.0f - uvIt->v;
                    v = uvIt->v;

                    out << "\t\t\t\t\t\t<texcoord ";
                    out << "u=\"" << u << "\" ";
			        out << "v=\"" << v << "\"/>\n";
			    }
            }
		    
            out << "\t\t\t\t\t</vertex>\n";
        }
           		
		out << "\t\t\t\t</vertexbuffer>\n";

        out << "\t\t\t</geometry>\n";


        // BONE ASSIGMENTS
        if(OPTIONS.exportVBA || OPTIONS.exportSkeleton) {
            out << "\t\t\t<boneassignments>\n";

            int i;
            for(i=0, vertexIt=FaceVertices.begin(); vertexIt!=vertexEnd; ++vertexIt, i++)	{            
                VertexBoneAssigmentList::iterator boneIt, boneEnd;
			    boneEnd = vertexIt->boneAssigments.end();
			    for (boneIt=vertexIt->boneAssigments.begin(); boneIt!=boneEnd; ++boneIt) {
                    VertexBoneAssigment& assigment = *boneIt;

                    if(assigment.weight<0.01)
                        continue;

                    out << "\t\t\t\t<vertexboneassignment ";
                    out << "vertexindex=\""<<i<<"\" ";
                    out << "boneindex=\""<<assigment.boneId<<"\" ";
                    out << "weight=\""<<assigment.weight<<"\"/>\n";           
                }
		    }
        

            out << "\t\t\t</boneassignments>\n";
        }


        out << "\t\t</submesh>\n";

////////////////////////////////////////////////////////////////////////////////


		// ===== Success!
		return MStatus::kSuccess;
	}

    MString MeshGenerator::getMaterialName(MFnMesh &fnMesh) {

		MStatus status = MStatus::kSuccess;
		MString MaterialName = "";
		

		// ===== Connected sets and members
		// (Required to determine texturing of different faces)

		// Determine instance number
        MDagPath meshPath = fnMesh.dagPath();
		meshPath.extendToShape();
		int iInstance = 0;
		if (meshPath.isInstanced()) {
			iInstance = meshPath.instanceNumber();
		}

		// Get the connected sets and members
		MObjectArray PolygonSets;
		MObjectArray PolygonComponents;
		status = fnMesh.getConnectedSetsAndMembers(iInstance, 
			                                       PolygonSets, 
												   PolygonComponents, 
												   true);
		if (!status) {
			MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers"); 
			return MaterialName;
		}


		// ===== Materials
		unsigned int iSet;
		for (iSet = 0; iSet < PolygonSets.length(); ++iSet) {
			MObject PolygonSet = PolygonSets[iSet];
			MObject PolygonComponent = PolygonComponents[iSet];

			MFnDependencyNode dnSet(PolygonSet);
			MObject ssAttr = dnSet.attribute(MString("surfaceShader"));
			MPlug ssPlug(PolygonSet, ssAttr);

⌨️ 快捷键说明

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