source: OGRE/trunk/ogrenew/Tools/MayaExport/shared/src/OgreMayaMesh.cpp @ 657

Revision 657, 27.3 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2============================================================================
3This source file is part of the Ogre-Maya Tools.
4Distributed as part of Ogre (Object-oriented Graphics Rendering Engine).
5Copyright (C) 2003 Fifty1 Software Inc., Bytelords
6
7This program is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20or go to http://www.gnu.org/licenses/gpl.txt
21============================================================================
22*/
23#include "OgreMayaMesh.h"
24#include "OgreMayaOptions.h"
25
26#include <maya/MItGeometry.h>
27#include <maya/MFnMesh.h>
28#include <maya/MDagPath.h>
29#include <maya/MDagPathArray.h>
30#include <maya/MSelectionList.h>
31#include <maya/MGlobal.h>
32#include <maya/MPlug.h>
33#include <maya/MFnLambertShader.h>
34#include <maya/MFnBlinnShader.h>
35#include <maya/MFnPhongShader.h>
36#include <maya/MFnReflectShader.h>
37#include <maya/MFnSet.h>
38#include <maya/MPlugArray.h>
39#include <maya/MItDependencyGraph.h>
40#include <maya/MItDag.h>
41
42#include <maya/MItDependencyNodes.h>
43#include <maya/MFnSkinCluster.h>
44
45#include <iostream>
46#include <string>
47
48#include <math.h>
49
50namespace OgreMaya {
51
52    using namespace std;
53
54        //      --------------------------------------------------------------------------
55        /** Standard constructor. Creates Ogre Mesh and defines known options.
56        */     
57        //      --------------------------------------------------------------------------
58        MeshGenerator::MeshGenerator() {
59        }
60
61
62        //      --------------------------------------------------------------------------
63        /** Destructor.
64        */     
65        //      --------------------------------------------------------------------------
66        MeshGenerator::~MeshGenerator()
67        {
68        }
69
70
71        //      --------------------------------------------------------------------------
72        /** Finds and exports all polygonal meshes in the DAG. Each polygonal mesh
73                corresponds to a single Ogre SubMesh.
74
75                \return         True if exported ok, false otherwise
76        */     
77        //      --------------------------------------------------------------------------
78        bool MeshGenerator::exportAll()
79        {
80                MStatus status;
81                bool bStatus = true;       
82
83                // ===== Iterate over mesh components of DAG
84
85                // --- Setup iterator
86                MItDag iterDag(MItDag::kDepthFirst, MFn::kMesh, &status);
87                if (status == MStatus::kFailure) {
88                        MGlobal::displayError("MItDag::MItDag");
89                        return false;
90                }
91
92
93        {
94            ofstream out(OPTIONS.outMeshFile.c_str());
95
96            out.precision(5);
97            out.setf(ios::fixed);
98       
99            out << "<mesh>\n";
100            out << "\t<submeshes>\n";
101
102                        MSelectionList list;
103                        MGlobal::getActiveSelectionList(list);
104
105                    // --- Iterate
106                    for(; !iterDag.isDone(); iterDag.next()) {
107                   
108                            // Get DAG path
109                            MDagPath dagPath;
110                            status = iterDag.getPath(dagPath);
111                            if (status == MStatus::kFailure) {
112                                    MGlobal::displayError("MDagPath::getPath");
113                                    bStatus = false;
114                                    break;
115                            }
116
117                            // Process this node?
118                                //if(OPTIONS.exportSelected && !list.hasItem(dagPath.node())) continue;
119                           
120                                if( dagPath.hasFn(MFn::kTransform)) continue;
121                            if(!dagPath.hasFn(MFn::kMesh))      continue;
122                           
123                                MFnDagNode dagNode(dagPath);
124                            if(dagNode.isIntermediateObject())  continue;
125
126                            // Process node if visible
127                            bool bVisible;
128                            bVisible = _isVisible(dagNode, status);
129                            if (bVisible && (status == MStatus::kSuccess)) {
130                                    status = _processPolyMesh(out, dagPath);
131                                    if (status != MStatus::kSuccess) {
132                                            break;
133                                    }
134                            }
135                    }
136
137            out << "\t</submeshes>\n";
138           
139            if(OPTIONS.exportSkeleton || OPTIONS.exportVBA) {
140                string skeletonName =
141                    OPTIONS.outSkelFile.substr(
142                        0, OPTIONS.outSkelFile.find_last_of('.')
143                    );
144                out << "\t<skeletonlink name=\""<<skeletonName<<"\"/>\n";
145            }
146
147            out << "</mesh>\n";
148        }
149
150                // reactivate IK Solver
151                MGlobal::executeCommand("ikSystem -e -sol 1;");
152
153                // ===== Done
154                return (status == MStatus::kSuccess);
155        }
156
157
158        //      --------------------------------------------------------------------------
159        /**     Process a Maya polyMesh to generate an Ogre SubMesh.
160
161                \param          dagPath
162                                        Path to the Maya polyMesh to be processed
163
164                \return         MStatus::kSuccess if processed successfuly,
165                                        different MStatus otherwise
166
167                \todo           Vertex optimization
168                \todo           Submesh optimization (merge submeshes that share materials)
169        */     
170        //      --------------------------------------------------------------------------
171        MStatus MeshGenerator::_processPolyMesh(ofstream& out, const MDagPath dagPath) {                       
172
173        cout << "\nMeshGenerator::_processPolyMesh\n";
174        cout << "\tdagPath = \"" << dagPath.fullPathName().asChar() << "\"\n";       
175
176        MStatus status = MStatus::kSuccess;
177        MeshMayaGeometry MayaGeometry;
178
179//*******************************************************************
180       
181        // ===== Calculate the influence of SkinCluter if any
182        bool hasSkinCluster = false;                                   
183           
184            //search the skin cluster affecting this geometry
185            MItDependencyNodes kDepNodeIt( MFn::kSkinClusterFilter );           
186
187        MFnMesh fnMesh(dagPath, &status);
188
189            for( ;!kDepNodeIt.isDone() && !hasSkinCluster; kDepNodeIt.next()) {           
190
191            MObject     kInputObject, kOutputObject;                   
192                    MObject kObject = kDepNodeIt.item();
193
194                    MFnSkinCluster kSkinClusterFn(kObject, &status);
195
196            cout << "\tskin cluster name: " << kSkinClusterFn.name().asChar() << '\n';
197
198
199            unsigned int uiNumGeometries = kSkinClusterFn.numOutputConnections();
200
201            cout << "\tfound " << uiNumGeometries << " geometry object(s) in skin cluster\n";
202
203            for(unsigned int uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) {
204                    unsigned int uiIndex = kSkinClusterFn.indexForOutputConnection( uiGeometry, &status );
205
206
207                    kInputObject = kSkinClusterFn.inputShapeAtIndex( uiIndex, &status );
208                    kOutputObject = kSkinClusterFn.outputShapeAtIndex( uiIndex, &status );
209
210                if(kOutputObject == fnMesh.object()) {
211                    cout << "\tgeometry located in skin cluster\n";
212                    hasSkinCluster = true;
213
214/*                   
215                    MDagPathArray jointPaths;
216                    kSkinClusterFn.influenceObjects(jointPaths, &status);
217                    int dummy;
218                        string rootName = jointPaths[0].partialPathName(&status).asChar();
219
220                        MGlobal::executeCommand("ikSystem -e -sol 0;");
221                        MGlobal::selectByName(rootName.c_str());
222                        MGlobal::executeCommand("dagPose -r -g -bp");
223*/
224
225                    // get weights
226                    MItGeometry kGeometryIt(kInputObject);
227                                for(int uiVertex = 0; !kGeometryIt.isDone(); kGeometryIt.next(), ++uiVertex ) {
228                                        MObject kComponent = kGeometryIt.component( 0 );
229
230                                        MFloatArray kWeightArray;
231                                        unsigned int uiNumInfluences;
232
233                                        kSkinClusterFn.getWeights(dagPath, kComponent, kWeightArray, uiNumInfluences);
234                                   
235                        MayaGeometry.Weights.push_back(kWeightArray);
236                    }
237                }
238            }
239       
240        }           
241                         
242       
243        // ===== Get Maya geometry             
244                status = _queryMayaGeometry(fnMesh, MayaGeometry);
245                if (status == MStatus::kFailure) {
246                        return status;
247                }
248
249/*
250        if(hasSkinCluster) {   
251                MGlobal::executeCommand("ikSystem -e -sol 1;");
252        }
253*/
254
255                // ===== Parse into MeshGenerator format
256                MeshFaceVertexVector FaceVertices;
257                MeshTriFaceList      TriFaces;
258                status = _parseMayaGeometry(fnMesh, MayaGeometry, FaceVertices, TriFaces);
259                if (status == MStatus::kFailure) {
260                        return status;
261                }
262
263
264////////////////////////////////////////////////////////////////////////////////
265               
266        // export as XML
267        out << "\t\t<submesh material=\"" << OPTIONS.matPrefix << MayaGeometry.MaterialName.asChar() << "\" usesharedvertices=\"false\" use32bitindexes=\"false\">\n";   
268       
269
270                // ===== Create Ogre face list
271                // --- Basic info
272                unsigned int nTriFaces = (unsigned int)TriFaces.size();
273                // --- Store face indices
274                MeshTriFaceList::iterator faceIt, faceEnd;
275        faceEnd = TriFaces.end();
276
277        out << "\t\t\t<faces count=\"" << nTriFaces << "\">\n";
278        for(faceIt=TriFaces.begin(); faceIt!=faceEnd; ++faceIt) {
279            out << "\t\t\t\t<face ";
280                        out << "v1=\"" << faceIt->index0 << "\" ";
281                        out << "v2=\"" << faceIt->index1 << "\" ";
282                        out << "v3=\"" << faceIt->index2 << "\"/>\n";
283                }
284        out << "\t\t\t</faces>\n";
285
286
287
288        out << "\t\t\t<geometry vertexcount=\"" << FaceVertices.size() << "\">\n";
289       
290
291                MeshFaceVertexVector::iterator vertexIt, vertexEnd;
292        vertexEnd = FaceVertices.end();
293
294        //
295        // POSITIONS
296        //
297        out << "\t\t\t\t<vertexbuffer ";
298        out << "positions=\"true\"";       
299        if(OPTIONS.exportNormals)
300            out << " normals=\"true\"";
301        if(OPTIONS.exportColours)
302            out << " colours_diffuse=\"true\"";
303        if(MayaGeometry.UVSets.size() > 0 && OPTIONS.exportUVs)         
304            out << " texture_coords=\"" << MayaGeometry.UVSets.size() << "\"";
305        out << ">\n";
306       
307       
308                for(vertexIt=FaceVertices.begin(); vertexIt!=vertexEnd; ++vertexIt)     {           
309            out << "\t\t\t\t\t<vertex>\n";
310           
311            out << "\t\t\t\t\t\t<position ";
312            out << "x=\"" << vertexIt->vecPosition.x << "\" ";
313                        out << "y=\"" << vertexIt->vecPosition.y << "\" ";
314                        out << "z=\"" << vertexIt->vecPosition.z << "\"/>\n";
315
316            if(OPTIONS.exportNormals) {
317                out << "\t\t\t\t\t\t<normal ";
318                out << "x=\"" << vertexIt->vecNormal.x << "\" ";
319                            out << "y=\"" << vertexIt->vecNormal.y << "\" ";
320                out << "z=\"" << vertexIt->vecNormal.z << "\"/>\n";
321            }
322
323
324            if(OPTIONS.exportColours) {           
325                out << "\t\t\t\t\t\t<colour_diffuse value=\"";
326                out << vertexIt->colour.r << " ";
327                            out << vertexIt->colour.g << " ";
328                out << vertexIt->colour.b << " ";
329                            out << vertexIt->colour.a << "\"/>\n";               
330                    }
331
332            if(MayaGeometry.UVSets.size() > 0 && OPTIONS.exportUVs) {
333                MeshVertexUVList::iterator uvIt, uvEnd;
334                            uvEnd = vertexIt->listUV.end();
335                            for (uvIt = vertexIt->listUV.begin(); uvIt!=uvEnd; ++uvIt) {                   
336
337                    float u,v;
338                    u = uvIt->u;
339                    //v = 1.0f - uvIt->v;
340                    v = uvIt->v;
341
342                    out << "\t\t\t\t\t\t<texcoord ";
343                    out << "u=\"" << u << "\" ";
344                                out << "v=\"" << v << "\"/>\n";
345                            }
346            }
347                   
348            out << "\t\t\t\t\t</vertex>\n";
349        }
350                       
351                out << "\t\t\t\t</vertexbuffer>\n";
352
353        out << "\t\t\t</geometry>\n";
354
355
356        // BONE ASSIGMENTS
357        if(OPTIONS.exportVBA || OPTIONS.exportSkeleton) {
358            out << "\t\t\t<boneassignments>\n";
359
360            int i;
361            for(i=0, vertexIt=FaceVertices.begin(); vertexIt!=vertexEnd; ++vertexIt, i++)       {           
362                VertexBoneAssigmentList::iterator boneIt, boneEnd;
363                            boneEnd = vertexIt->boneAssigments.end();
364                            for (boneIt=vertexIt->boneAssigments.begin(); boneIt!=boneEnd; ++boneIt) {
365                    VertexBoneAssigment& assigment = *boneIt;
366
367                    if(assigment.weight<0.01)
368                        continue;
369
370                    out << "\t\t\t\t<vertexboneassignment ";
371                    out << "vertexindex=\""<<i<<"\" ";
372                    out << "boneindex=\""<<assigment.boneId<<"\" ";
373                    out << "weight=\""<<assigment.weight<<"\"/>\n";           
374                }
375                    }
376       
377
378            out << "\t\t\t</boneassignments>\n";
379        }
380
381
382        out << "\t\t</submesh>\n";
383
384////////////////////////////////////////////////////////////////////////////////
385
386
387                // ===== Success!
388                return MStatus::kSuccess;
389        }
390
391    MString MeshGenerator::getMaterialName(MFnMesh &fnMesh) {
392
393                MStatus status = MStatus::kSuccess;
394                MString MaterialName = "";
395               
396
397                // ===== Connected sets and members
398                // (Required to determine texturing of different faces)
399
400                // Determine instance number
401        MDagPath meshPath = fnMesh.dagPath();
402                meshPath.extendToShape();
403                int iInstance = 0;
404                if (meshPath.isInstanced()) {
405                        iInstance = meshPath.instanceNumber();
406                }
407
408                // Get the connected sets and members
409                MObjectArray PolygonSets;
410                MObjectArray PolygonComponents;
411                status = fnMesh.getConnectedSetsAndMembers(iInstance,
412                                                               PolygonSets,
413                                                                                                   PolygonComponents,
414                                                                                                   true);
415                if (!status) {
416                        MGlobal::displayError("MFnMesh::getConnectedSetsAndMembers");
417                        return MaterialName;
418                }
419
420
421                // ===== Materials
422                unsigned int iSet;
423                for (iSet = 0; iSet < PolygonSets.length(); ++iSet) {
424                        MObject PolygonSet = PolygonSets[iSet];
425                        MObject PolygonComponent = PolygonComponents[iSet];
426
427                        MFnDependencyNode dnSet(PolygonSet);
428                        MObject ssAttr = dnSet.attribute(MString("surfaceShader"));
429                        MPlug ssPlug(PolygonSet, ssAttr);
430
431                        MPlugArray srcPlugArray;
432                        ssPlug.connectedTo(srcPlugArray, true, false);
433                       
434                        if (srcPlugArray.length() > 0) {
435                                // This object contains a reference to a shader or material.
436                                // Check for known material types and extract material name.
437                                MObject srcNode = srcPlugArray[0].node();
438                               
439                                if (srcNode.hasFn(MFn::kPhong)) {
440                                        MFnPhongShader fnPhong(srcNode);
441                                        MaterialName = fnPhong.name();
442                }
443                                else if (srcNode.hasFn(MFn::kLambert)) {
444                                        MFnLambertShader fnLambert(srcNode);
445                                        MaterialName = fnLambert.name();
446                                }
447                                else if (srcNode.hasFn(MFn::kBlinn)) {
448                                        MFnBlinnShader fnBlinn(srcNode);
449                                        MaterialName = fnBlinn.name();
450                                }
451                                else if (srcNode.hasFn(MFn::kReflect)) {
452                                        MFnReflectShader fnReflect(srcNode);
453                                        MaterialName = fnReflect.name();
454                                }
455            }
456                }
457
458
459                // ===== Done
460                return MaterialName;
461
462        }
463
464        //      --------------------------------------------------------------------------
465        /**     Retrieve all Maya geometry for a single Maya mesh.
466                \todo           Define materials if requested
467                \todo           Fix normals
468        */     
469        //      --------------------------------------------------------------------------
470        MStatus MeshGenerator::_queryMayaGeometry(
471        MFnMesh &fnMesh,
472                MeshMayaGeometry &rGeom
473    ) {
474        cout << "\nMeshGenerator::_queryMayaGeometry\n";
475
476                MStatus status = MStatus::kSuccess;               
477
478                // ===== Identification         
479        rGeom.Name         = fnMesh.partialPathName(); // shortest unique name       
480                rGeom.MaterialName = getMaterialName(fnMesh);       
481
482
483                // ===== Geometry
484
485                // --- Vertices
486                status = fnMesh.getPoints(rGeom.Vertices, MSpace::kWorld);
487                if (status == MStatus::kFailure) {
488                        cout << "\t[ERROR] MFnMesh::getPoints() failed\n";
489                        return status;
490                }
491
492        cout << "\tvertices count: " << rGeom.Vertices.length() << '\n';
493
494                // --- Vertex normals
495                status = fnMesh.getNormals(rGeom.FaceVertexNormals);
496                if (status == MStatus::kFailure) {
497                        cout << "\t[ERROR] MFnMesh::getNormals() failed\n";
498                        return status;
499                }
500
501                // --- Triangular faces
502                MDagPath dagPath;
503                fnMesh.getPath(dagPath);
504                MItMeshPolygon iterPoly(dagPath);
505               
506                int iPolygon, nPolygons;
507                nPolygons = fnMesh.numPolygons();
508                for (iPolygon=0; iPolygon < nPolygons; ++iPolygon)
509                {
510                        MIntArray ThisPolyTriVertices;
511                        MPointArray ThisPolyPointsUntweaked;
512                        iterPoly.getTriangles(ThisPolyPointsUntweaked, ThisPolyTriVertices, MSpace::kWorld);
513
514                        _convertObjectToFace(iterPoly, ThisPolyTriVertices, rGeom.TriangleVertexIds);
515
516                        int iTriangle, nTriangles;
517                        iterPoly.numTriangles(nTriangles);
518                        for (iTriangle=0; iTriangle < nTriangles; ++iTriangle) {
519                                rGeom.TrianglePolygonIds.append(iPolygon);
520                        }
521
522                        iterPoly.next();
523                }
524
525
526                // ===== Colours and UVs
527
528                // --- Face vertex colours
529                status = fnMesh.getFaceVertexColors(rGeom.FaceVertexColours);
530                if (status == MStatus::kFailure) {
531                        cout << "\t[ERROR] MFnMesh::getFaceVertexColors() failed\n";
532                        return status;
533                }
534                // Override non-existent colours with semi-transparent white
535                unsigned int iFaceVertex;
536                MColor mayaColour;
537                for (iFaceVertex=0; iFaceVertex < rGeom.FaceVertexColours.length(); ++iFaceVertex) {
538                        mayaColour = rGeom.FaceVertexColours[iFaceVertex];
539                        if ((mayaColour.r) == -1) mayaColour.r = 1;
540                        if ((mayaColour.g) == -1) mayaColour.g = 1;
541                        if ((mayaColour.b) == -1) mayaColour.b = 1;
542                        if ((mayaColour.a) == -1) mayaColour.a = 0.2;
543                        rGeom.FaceVertexColours[iFaceVertex] = mayaColour;
544                }
545
546                // --- UV set names
547                MStringArray UVSetNames;
548                status = fnMesh.getUVSetNames(UVSetNames);
549                if (status == MStatus::kFailure) {
550                        cout << "\t[ERROR] MFnMesh::getUVSetNames() failed\n";
551                        return status;
552                }
553
554                // --- Linked list of UV sets
555                unsigned int nUVSets = UVSetNames.length();
556                unsigned int iUVSet;
557
558                // Loop over all UV sets
559                MeshMayaUVSet UVSet;
560                for (iUVSet = 0; iUVSet < nUVSets; ++iUVSet) {
561
562                        // Store UV name
563                        UVSet.sName = UVSetNames[iUVSet];
564
565                        // Retrieve UV coordinates
566                        status = fnMesh.getUVs(UVSet.uArray, UVSet.vArray, &(UVSet.sName));
567                        if (status == MStatus::kFailure) {
568                                return status;
569                        }
570
571                        // Store UV set
572                        rGeom.UVSets.push_back(UVSet);
573                }
574
575
576                // ===== Done
577                return status;
578
579        }
580
581
582        //      --------------------------------------------------------------------------
583        /** Parse Maya geometry into MeshGenerator format for further processing.
584        */     
585        //      --------------------------------------------------------------------------
586        MStatus MeshGenerator::_parseMayaGeometry(
587        MFnMesh &fnMesh,
588                MeshMayaGeometry &MayaGeometry,
589                MeshFaceVertexVector &FaceVertices,
590                MeshTriFaceList &TriFaces
591    ) {
592        cout << "\nMeshGenerator::_parseMayaGeometry\n";
593
594                MStatus status;
595
596                // --- Determine number of triangles
597                unsigned int nTris = MayaGeometry.TrianglePolygonIds.length();
598                if (nTris == 0) {
599                        return MStatus::kFailure;
600                }
601
602                // --- Confirm number of triangle vertices
603                unsigned int nTriVertices = MayaGeometry.TriangleVertexIds.length();
604                if (nTriVertices != 3*nTris) {
605                        cout << "\t[ERROR] "<<nTris<<" triangles require "<<(3*nTris)<<" vertices but "<<nTriVertices<<" vertices present!\n";
606                        return MStatus::kFailure;
607                }
608
609                // --- Loop over all triangles
610                unsigned int iTri;
611                cout << "\texporting "<<fnMesh.numPolygons()<<" faces as "<<nTris<<" triangles from "<<MayaGeometry.Name.asChar()<<" (material "<<MayaGeometry.MaterialName.asChar()<<")...\n";
612
613                for (iTri = 0; iTri < nTris; ++iTri) {
614
615                        // --- Get polygon index
616                        unsigned int iPoly;
617                        iPoly = MayaGeometry.TrianglePolygonIds[iTri];
618
619                        // --- Get indices of face-vertices
620                        MIntArray VertexIds;
621                        status = fnMesh.getPolygonVertices(iPoly, VertexIds);
622                        if (status == MStatus::kFailure) {
623                                MGlobal::displayError("MFnMesh::getPolygonVertices()");
624                                return status;
625                        }
626
627                        // --- Get indices of face-vertex normals
628                        MIntArray NormalIds;
629                        /*if (OPTIONS.exportNormals)*/ {
630                                fnMesh.getFaceNormalIds(iPoly, NormalIds);
631                                if (status == MStatus::kFailure) {
632                                        MGlobal::displayError("MFnMesh::getFaceNormalIds()");
633                                        return status;
634                                }
635                        }
636
637                        // --- Loop over all face-vertices
638                        unsigned int iTriVertex;
639            MeshFaceVertex faceVertices[3];
640                        for (iTriVertex = 0; iTriVertex < 3; ++iTriVertex) {
641                               
642                                MeshFaceVertex& FaceVertex = faceVertices[iTriVertex];
643
644                                // Get polygon vertex id
645                                unsigned int iPolyVertex;
646                                iPolyVertex = MayaGeometry.TriangleVertexIds[3*iTri + iTriVertex];
647
648                                // Lookup and store face-vertex position
649                                MPoint mayaPoint;
650                                int iVertex = VertexIds[iPolyVertex];
651                                mayaPoint = MayaGeometry.Vertices[iVertex];
652               
653                MFloatArray* weights = 0;
654
655                if(iVertex < MayaGeometry.Weights.size()) {
656                    weights = &MayaGeometry.Weights[iVertex];
657                }
658
659                                FaceVertex.vecPosition.x = mayaPoint.x;
660                                FaceVertex.vecPosition.y = mayaPoint.y;
661                                FaceVertex.vecPosition.z = mayaPoint.z;
662
663                                // Lookup and store face-vertex normal
664                                /*if (OPTIONS.exportNormals)*/ {
665                                        MVector mayaNormal;
666                                        int iNormal = NormalIds[iPolyVertex];
667                                        mayaNormal = MayaGeometry.FaceVertexNormals[iNormal];
668                                        FaceVertex.vecNormal.x = mayaNormal.x;
669                                        FaceVertex.vecNormal.y = mayaNormal.y;
670                                        FaceVertex.vecNormal.z = mayaNormal.z;
671                                }
672
673                                // Lookup and store face-vertex colour
674                                /*if (OPTIONS.exportColours)*/ {
675                                        int iColour;
676                                        MColor mayaColour;
677                                        status = fnMesh.getFaceVertexColorIndex(iPoly, iPolyVertex, iColour);
678                                        mayaColour = MayaGeometry.FaceVertexColours[iColour];
679                                        FaceVertex.colour.r = mayaColour.r;
680                                        FaceVertex.colour.g = mayaColour.g;
681                                        FaceVertex.colour.b = mayaColour.b;
682                                        FaceVertex.colour.a = mayaColour.a;
683                                }
684
685                                // Loop over UV sets
686                                /*if (OPTIONS.exportUVs)*/ {
687                                        MeshMayaUVSetList::iterator iterUVSet;
688                                        iterUVSet = MayaGeometry.UVSets.begin();
689                                        while (iterUVSet != MayaGeometry.UVSets.end()) {                       
690                                                int iUV;
691                                                MStatus stat = fnMesh.getPolygonUVid(iPoly, iPolyVertex, iUV, &(iterUVSet->sName));
692                                       
693                                                MeshVertexUV VertexUV;
694                        if(!stat.error()) {                                                 
695                                                    VertexUV.u = iterUVSet->uArray[iUV];
696                                                    VertexUV.v = 1.0f - iterUVSet->vArray[iUV]; // CJV 2004-01-05: Required for Ogre 0.13
697                                }
698                                                else {
699                                                        VertexUV.u = 0;
700                                                        VertexUV.v = 0;
701                                                }
702
703                                                FaceVertex.listUV.push_back(VertexUV);
704                                               
705                        ++iterUVSet;                       
706                                        }
707                                }
708
709                // assign weights
710                if(weights) {
711                    const float eps = 0.001f;
712                    float acc;                   
713
714                    for(int i=weights->length()-1; i>=0; i--) {
715                        acc = 0;
716                        if((*weights)[i] < eps) {
717                            acc += (*weights)[i];
718                        }
719                        else {
720                            VertexBoneAssigment vba;
721
722                            vba.boneId   = i;                           
723                            vba.weight   = (*weights)[i];// + (acc/(float)i);
724
725                            FaceVertex.boneAssigments.push_front(vba);
726                        }
727                    }                   
728                }
729                        }
730
731
732           
733            // OPTIMIZIATION CODE: BEGIN
734            // Search in the current vertex vector for occurance           
735            int index[3];
736            for(int i=0; i<3; i++) {
737               
738                vector<MeshFaceVertex>::iterator it;
739                vector<MeshFaceVertex>::iterator end = FaceVertices.end();
740               
741                int j;
742                for(j=0, it=FaceVertices.begin(); it!=end; ++it, j++) {
743                    if(faceVertices[i] == *it) {
744                        // this vertex is already in vector -> reuse
745                        index[i] = j;
746                        break;
747                    }
748                }
749
750                // if can not be found in vector, insert
751                if(it==end) {
752                    index[i] = FaceVertices.size();
753                    FaceVertices.push_back(faceVertices[i]);
754                }
755            }
756            // OPTIMIZIATION CODE: END
757           
758
759                        // --- Define face (three face-vertices)
760                        MeshTriFace TriFace;
761                        TriFace.index0 = (unsigned long)index[0];
762                        TriFace.index1 = (unsigned long)index[1];
763                        TriFace.index2 = (unsigned long)index[2];
764
765                        TriFaces.push_back(TriFace);
766                }
767
768                return MStatus::kSuccess;
769        }
770   
771
772        //      --------------------------------------------------------------------------
773        /** Determines if a given DAG node is currently visible.
774                \param          fnDag
775                                        DAG node to check
776                \param          status
777                                        Status code from Maya API
778
779                \return         True if node is visible, False if node is not visible or if
780                                        unable to determine visibility
781        */     
782        //      --------------------------------------------------------------------------
783        bool MeshGenerator::_isVisible(MFnDagNode &fnDag, MStatus &status) {                   
784
785        if(fnDag.isIntermediateObject()) {
786                        return false;
787                }
788
789                bool bVisible = false;
790                MPlug visPlug = fnDag.findPlug("visibility", &status);
791                if (MStatus::kFailure == status) {
792                        cout << "[WARNING] can not find \"visibility\" plug, returning false\n";
793                } else {
794                        status = visPlug.getValue(bVisible);
795                        if (MStatus::kFailure == status) {
796                                bVisible = false;
797                cout << "[WARNING] can not query \"visibility\" plug, returning false\n";
798                        }
799                }
800
801                return bVisible;
802        }
803
804
805        //      --------------------------------------------------------------------------
806        /** Convert an array of object-relative vertex indices into an array of face-
807                relative vertex indices. Required because MItMeshPolygon::getTriangle()
808                returns object-relative vertex indices, whereas many other methods require
809                face-relative vertex indices.
810
811                Adapted from "How do I write a polygon mesh exporter?" at URL
812                http://www.ewertb.com/maya/api/api_a18.html.
813
814                \param          iterPoly
815                                        Reference to a polygon iterator that is currently at the
816                                        polygon of interest
817                \param          objIndices
818                                        Reference to array of object-relative indices
819                \param          faceIndices
820                                        Reference to array of face-relative indices (output). Indices
821                                        are appended to the end of this array. A value of -1 will be
822                                        appended if there is no corresponding vertex.
823        */     
824        //      --------------------------------------------------------------------------
825        void MeshGenerator::_convertObjectToFace(
826        MItMeshPolygon &iterPoly,
827                MIntArray &objIndices,
828                MIntArray &faceIndices
829    ) {
830                MIntArray polyIndices;
831                iterPoly.getVertices(polyIndices);
832                       
833                bool bMatched;
834                unsigned int iPoly, iObj;
835                for (iObj=0; iObj < objIndices.length(); ++iObj)
836                {
837                        bMatched = false;
838                       
839                        // iPoly is face-relative vertex index
840                        for (iPoly=0; iPoly < polyIndices.length(); ++iPoly)
841                        {
842                                if (objIndices[iObj] == polyIndices[iPoly]) {
843                                        faceIndices.append(iPoly);
844                                        bMatched = true;
845                                        break;
846                                }
847
848                        }
849
850                        // default if no match found
851                        if (!bMatched) {
852                                faceIndices.append(-1);
853                        }
854
855                }
856        }
857       
858
859} // namespace OgreMaya
Note: See TracBrowser for help on using the repository browser.