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

📄 ogreexporter.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#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 + -