📄 ogreexporter.cpp
字号:
#include "OgreExporter.h"
#include "Ogre.h"
//#include <crtdbg.h>
#include <zlib.h>
/*
#include <maya/MFnDagNode.h>
#include <maya/MDagPath.h>
#include <maya/MFnDependencyNode.h>
#include <maya/M3dView.h>
#include <maya/MItDependencyGraph.h>
*/
#include <maya/MFnMesh.h>
#include <maya/MItDag.h>
#include <maya/MFnPlugin.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MItMeshVertex.h>
#include <maya/MFloatPointArray.h>
#include <maya/MPointArray.h>
#include <maya/MMatrix.h>
#include <vector>
#include <functional>
#include <algorithm>
#include "Windows.h"
const char* const c_pPlugName = "OgreGeometry";
MayaMesh::MayaMesh( const MDagPath &meshDagPath, const MDagPath &meshParentPath, const MObject &meshObject ) :
m_meshDagPath ( meshDagPath ),
m_meshParentPath( meshParentPath ),
m_meshObject ( meshObject )
{
}
MayaBone::MayaBone( const MDagPath &boneDagPath, const MDagPath &boneParentPath, const MObject &boneObject ) :
m_boneDagPath ( boneDagPath ),
m_boneParentPath( boneParentPath ),
m_boneObject ( boneObject ),
m_references ( 0 )
{
}
OgreExporter::OgreExporter()
{
}
void* OgreExporter::creator()
{
return new OgreExporter;
}
MDagPath GetParentDagPath(const MDagPath& path)
{
MDagPath pathToParent(path);
while (pathToParent.pop() == MS::kSuccess)
{
if (pathToParent.node().hasFn(MFn::kTransform))
return pathToParent;
}
return pathToParent;
}
void collectStuff( std::vector< MayaMesh > * const pMeshes, std::vector< MayaBone > * const pBones )
{
assert(pMeshes);
assert(pBones);
assert( pMeshes->size() == 0 );
//pMeshes->resize(0);
//pBones->resize(0);
MItDag dag_itr( MItDag::kDepthFirst, MFn::kInvalid );
while( dag_itr.isDone() == false )
{
MDagPath dagPath;
dag_itr.getPath( dagPath );
const MFnDagNode dagNode( dagPath );
if (dagNode.isIntermediateObject())
{
dag_itr.next();
continue;
}
if ( dagPath.hasFn(MFn::kMesh) &&
!dagPath.hasFn(MFn::kTransform) )
{
pMeshes->push_back( MayaMesh( dagPath, GetParentDagPath( dagPath ), dag_itr.item() ) );
}
else if (dag_itr.item().apiType() == MFn::kJoint ||
dag_itr.item().apiType() == MFn::kTransform)
{
MDagPath boneDagPath;
dag_itr.getPath( boneDagPath );
pBones->push_back( MayaBone( boneDagPath, GetParentDagPath( boneDagPath ), dag_itr.item() ) );
}
dag_itr.next();
}
}
class IndirectVert
{
public:
IndirectVert( void ) :
m_newVertIndex( -1 ),
m_posIndex ( -1 ),
m_normalIndex ( -1 ),
m_uv0Index ( -1 ),
m_colorIndex ( -1 )
{
calcHash();
}
IndirectVert( const int newVertIndex, const int posIndex, const int normalIndex, const int uv0Index, const int colorIndex ) :
m_newVertIndex( newVertIndex ),
m_posIndex ( posIndex ),
m_normalIndex ( normalIndex ),
m_uv0Index ( uv0Index ),
m_colorIndex ( colorIndex )
{
calcHash();
}
void calcHash(void)
{
unsigned char* buf = new unsigned char[sizeof(int) * 4];
unsigned char* pBuf = buf;
memcpy(pBuf, &m_posIndex, sizeof(int));
pBuf += sizeof(int);
memcpy(pBuf, &m_normalIndex, sizeof(int));
pBuf += sizeof(int);
memcpy(pBuf, &m_uv0Index, sizeof(int));
pBuf += sizeof(int);
memcpy(pBuf, &m_colorIndex, sizeof(int));
// Use zlib crc32
unsigned long crc = crc32(0L, Z_NULL, 0);
m_hash = crc32(crc, buf, sizeof(int) * 4);
}
const unsigned long hash( void ) const
{
return m_hash;
}
bool operator ==( const IndirectVert &other ) const
{
return m_posIndex == other.m_posIndex &&
m_normalIndex == other.m_normalIndex &&
m_uv0Index == other.m_uv0Index &&
m_colorIndex == other.m_colorIndex;
}
bool operator !=( const IndirectVert &other ) const
{
return !(m_hash == other.m_hash);
}
bool operator <( const IndirectVert &other ) const
{
return m_hash < other.m_hash;
}
//Ease of access. Privitise later.
//Does not participate in hashing
int m_newVertIndex;
//Participate in the hashing.
int m_posIndex;
int m_normalIndex;
int m_uv0Index;
int m_colorIndex;
private:
unsigned long m_hash;
};
typedef std::hash_set< IndirectVert > IndVertHS;
struct std::hash<IndirectVert>
{
size_t operator ()( const IndirectVert &vert ) const
{
return vert.hash();
}
};
/*
void uniqueifyVerts
(
std::vector< IndirectVert > * const vertList,
const std::vector< int > &posIndices,
const std::vector< int > &normalIndices,
const std::vector< int > &uv0Indices,
const std::vector< int > &colorIndices
)
{
assert( posIndices.size() == normalIndices.size() == uv0Indices.size() == colorIndices.size() );
std::hash_set< IndirectVert > m_vertHash;
const int numVerts = posIndices.size();
for( int i=0; i<numVerts; ++i )
{
const IndirectVert vert( posIndices[ i ], normalIndices[ i ], uv0Indices[ i ], colorIndices[ i ] );
if( m_vertHash.find( vert )
}
}
*/
MStatus exportMesh( const MayaMesh &mesh, Ogre::Mesh * const ogreMesh )
{
MStatus stat = MS::kSuccess;
const MSpace::Space space = MSpace::kWorld;
MFnMesh fnMesh( mesh.path(), &stat );
if ( MS::kSuccess != stat)
{
fprintf(stderr,"Failure in MFnMesh initialization.\n");
return MS::kFailure;
}
const MMatrix matrix = mesh.path().inclusiveMatrix( &stat );
const float det44 = matrix.det4x4();
bool reverseWinding = false;
if( det44 < 0.0f )
{
reverseWinding = true;
}
MItMeshVertex vtxIter( mesh.object(), &stat );
if ( MS::kSuccess != stat)
{
fprintf(stderr,"Failure in MItMeshVertex initialization.\n");
return MS::kFailure;
}
Ogre::SubMesh * const ogreSubMesh = ogreMesh->createSubMesh();
//Default ugly texture for the moment.
ogreSubMesh->setMaterialName( "Examples/Test" );
// Set up mesh geometry
// Always 1 texture layer, 2D coords
ogreSubMesh->geometry.numTexCoords = 1;
ogreSubMesh->geometry.numTexCoordDimensions[0] = 2;
ogreSubMesh->geometry.hasNormals = true;
ogreSubMesh->geometry.hasColours = false;
ogreSubMesh->geometry.vertexStride = 0;
ogreSubMesh->geometry.texCoordStride[0] = 0;
ogreSubMesh->geometry.normalStride = 0;
ogreSubMesh->useSharedVertices = false;
ogreSubMesh->useTriStrips = false;
/*
// Fill in vertex table
std::vector< MPoint > points;
for ( ; !vtxIter.isDone(); vtxIter.next() )
{
const MPoint pt = vtxIter.position( space, &stat );
const MPoint ptWorld = vtxIter.position( MSpace::kWorld , &stat );
const MPoint ptLocal = vtxIter.position( MSpace::kObject, &stat );
points.push_back( pt );
}
*/
MFloatPointArray points;
fnMesh.getPoints( points, space );
MFloatVectorArray norms;
fnMesh.getNormals( norms, space );
//const int normsLength = norms.length();
// Write out the uv table
MFloatArray uArray, vArray;
fnMesh.getUVs( uArray, vArray );
//const int uvLength = uArray.length();
assert( uArray.length() == vArray.length() );
ogreSubMesh->numFaces = fnMesh.numPolygons( &stat );
MItMeshPolygon polyIter( mesh.object(), &stat );
if ( MS::kSuccess != stat)
{
fprintf( stderr, "Failure in MItMeshPolygon initialization.\n" );
return stat;
}
std::vector< int > faceIndices;
std::vector< IndirectVert > vertList;
std::hash_set< IndirectVert > vertHash;
int curVert = 0;
for ( ; !polyIter.isDone(); polyIter.next() )
{
const int vertCount = polyIter.polygonVertexCount( &stat );
int start = 0;
int end = 3;
int delta = 1;
if( reverseWinding )
{
start = 2;
end = -1;
delta = -1;
}
for( int i = start; i != end; i+=delta )
{
const int posIndex = polyIter.vertexIndex( i, &stat );
const int normalIndex = polyIter.normalIndex( i, &stat );
int uv0Index;
polyIter.getUVIndex( i, *&uv0Index );
const IndirectVert potentialNewVert( vertList.size(), posIndex, normalIndex, uv0Index, -1 );
const IndVertHS::iterator it = vertHash.find( potentialNewVert );
if( it != vertHash.end() )
{
const IndirectVert vert = *it;
faceIndices.push_back( vert.m_newVertIndex );
}
else
{
vertHash.insert( potentialNewVert );
vertList.push_back( potentialNewVert );
faceIndices.push_back( potentialNewVert.m_newVertIndex );
}
}
}
ogreSubMesh->geometry.numVertices = vertList.size();
ogreSubMesh->geometry.pVertices = new Ogre::Real[ogreSubMesh->geometry.numVertices * 3];
ogreSubMesh->geometry.pNormals = new Ogre::Real[ogreSubMesh->geometry.numVertices * 3];
ogreSubMesh->geometry.pTexCoords[0] = new Ogre::Real[ogreSubMesh->geometry.numVertices * 2];
for( int i=0; i<vertList.size(); ++i )
{
const IndirectVert &vert = vertList[i];
{
const int posIndex = vert.m_posIndex;
assert( posIndex >= 0 );
assert( posIndex < points.length() );
const MFloatPoint &pt = points[ posIndex ];
const int posBaseIndex = i * 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -