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

📄 lwo2mesh.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "Vector3.h"
#include "lwo2mesh.h"
#include "Ogre.h"
#include "OgreMesh.h"
#include "OgreStringConverter.h"
#include "OgreDefaultHardwareBufferManager.h"

#if OGRE_PLATFORM == PLATFORM_LINUX
#include <math.h>
#include <float.h>  // FLT_MIN, FLT_MAX
#include <libgen.h> // dirname(), basename().
#include <string.h> // strtok();
#include <string>   // string class
#endif

#define POLYLIMIT 0x5555
#define POINTLIMIT 0x5555

extern Mesh::LodDistanceList distanceList;
extern Real reduction;
extern bool flags[NUMFLAGS];
extern MaterialSerializer* materialSerializer;
extern char *matPrefix;

extern ostream& nl(ostream& os);

#if OGRE_PLATFORM == PLATFORM_LINUX

/* We expect the caller to provide an arrays of chars for the output. */
void _splitpath( const char *_fn, char *_drive, char *_dir, char *_node, char *_ext ) {
       
   /* A crazy mix of both c and c++.. */
       
   const char *delimiters = ".";
   char buf[ _MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT + 5 ];
   char *exte, *ddir, *fnam, *_ext_tmp;

   strcpy( buf, _fn );
   strcpy( _drive, "" ); // _drive is always empth on linux.

   if ( String( buf ).empty() ) {
       strcpy( _node, "" );
       strcpy( _dir, "" );
       strcpy( _ext, "" );
       return;
   } 
   
   fnam = basename( buf );
   strcpy( _node, fnam );
   ddir = dirname( buf );
   strcpy( _dir, ddir );
   
   _ext_tmp = strtok( fnam, delimiters );
   while ( ( _ext_tmp = strtok( NULL, delimiters ) ) != NULL ) exte = _ext_tmp;
   strcpy( _ext, exte );

   _node[ strlen(_node) - strlen(_ext) - 1 ] = '\0';

}

/* We expect the caller to provide an array of chars for the output. */
void _makepath( char *_fn, const char *_drive, const char *_dir,
       const char *_node, const char *_ext ) {
   
   /* A crazy mix of both c and c++.. */

   std::string buf("");

   if ( _drive != NULL ) // On Linux, this is usually empty.
       buf += _drive;
       
   if ( _dir != NULL ) { // The directory part.
       if ( std::string(_dir).empty() )
           buf += ".";
       buf += _dir;
       buf += "/";
   }
   
   if ( _node != NULL ) // The filename without the extension.
       buf += _node;
   
   if ( _ext != NULL ) { // The extension.
       if ( std::string( _ext ).compare( 0, 1, "." ) != 0 )
           buf += ".";
       buf += _ext;
   }

   strcpy( _fn, buf.c_str() );
}

#endif

void Lwo2MeshWriter::doExportMaterials()
{
	char
		drive[ _MAX_DRIVE ],
		dir[ _MAX_DIR ],
		node[ _MAX_FNAME ],
		ext[ _MAX_EXT ],
		texname [128];

	unsigned int slength = 0;

	if (flags[RenameMaterials])
	{
		if (flags[UseInteractiveMethod])
		{
			for (unsigned int i = 0; i < object->surfaces.size(); ++i)
			{		
				lwSurface *surface = object->surfaces[i];
				cout << "Rename surface " << surface->name << " to: ";
				cin >> texname;
				surface->setname(texname);
			}
		} else {
			_splitpath( dest, drive, dir, node, ext );

			for (unsigned int i = 0; i < object->surfaces.size(); ++i)
			{
				lwSurface *surface = object->surfaces[i];
				if (flags[UsePrefixMethod])
					strcpy(texname,matPrefix);
				else
				{
					strcpy(texname,node);
					strcat(texname,"_");
				}

				strcat(texname, surface->name);
				surface->setname(texname);
			}
		}
	}

	for (unsigned int i = 0; i < object->surfaces.size(); ++i)
	{		
		lwSurface *surface = object->surfaces[i];

		// Create deferred material so no load
		Material* ogreMat = (Material*)MaterialManager::getSingleton().getByName(surface->name);
		
		if (!ogreMat)
		{
			ogreMat = (Material*)MaterialManager::getSingleton().create(surface->name);
			
			ogreMat->setAmbient
			(
				surface->color.rgb[0],
				surface->color.rgb[1],
				surface->color.rgb[2]
			);
			
			ogreMat->setDiffuse
			(
				surface->diffuse.val * surface->color.rgb[0],
				surface->diffuse.val * surface->color.rgb[1],
				surface->diffuse.val * surface->color.rgb[2],
				1.0f
			);
			
			ogreMat->setSpecular
			(
				surface->specularity.val * surface->color.rgb[0],
				surface->specularity.val * surface->color.rgb[1],
				surface->specularity.val * surface->color.rgb[2],
				1.0f
			);
			
			ogreMat->setShininess(surface->glossiness.val);
			
			ogreMat->setSelfIllumination
			(
				surface->luminosity.val * surface->color.rgb[0],
				surface->luminosity.val * surface->color.rgb[1],
				surface->luminosity.val * surface->color.rgb[2]
			);
			
			for (unsigned int j = 0; j < surface->color.textures.size(); j++)
			{
				lwTexture *tex = surface->color.textures[j];
				int cindex = tex->param.imap->cindex;
				lwClip *clip = object->lwFindClip(cindex);
				
				if (clip)
				{
					_splitpath( clip->source.still->name, drive, dir, node, ext );
					_makepath( texname, 0, 0, node, ext );					
					ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname);
				}
			}			
			materialSerializer->queueForExport(ogreMat);
		}
	}
}

Skeleton *Lwo2MeshWriter::doExportSkeleton(const String &skelName, int l)
{
	vpolygons bones;
	bones.clear();
	bones.reserve(256);

	vpoints bonepoints;
	bonepoints.clear();
	bonepoints.reserve(512);

	if (l == -1)
	{
		for (l = 0; l < object->layers.size(); ++l)
		{
			copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
			copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
		}
	}
	else
	{
		copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
		copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
	}

	if (!bones.size()) return NULL; // no bones means no skeleton

	Skeleton *ogreskel = new Skeleton(skelName);

	unsigned int i;
	// Create all the bones in turn
	for (i = 0; i < bones.size(); ++i)
	{
		lwPolygon* bone = bones[i];
		if (bone->vertices.size() != 2) continue; // a bone has only 2 sides

		Bone* ogreBone = ogreskel->createBone("Bone");

		Ogre::Vector3 bonePos(bone->vertices[0]->point->x, bone->vertices[0]->point->y, bone->vertices[0]->point->z);

		ogreBone->setPosition(bonePos);
		// Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart
		// Rotation Matrix or Quaternion would have been the smarter choice
		// Might we have Gimbal lock here? What order are these 3 angles supposed to be applied?
		// Grr, we'll try our best anyway...
		Quaternion qx, qy, qz, qfinal;
/*
		qx.FromAngleAxis(msBoneRot[0], Vector3::UNIT_X);
		qy.FromAngleAxis(msBoneRot[1], Vector3::UNIT_Y);
		qz.FromAngleAxis(msBoneRot[2], Vector3::UNIT_Z);
*/
		// Assume rotate by x then y then z
		qfinal = qz * qy * qx;
		ogreBone->setOrientation(qfinal);
	}
/*
	for (i = 0; i < numBones; ++i)
	{
		msBone* bone = msModel_GetBoneAt(pModel, i);

		if (strlen(bone->szParentName) == 0)
		{
		}
		else
		{
			Bone* ogrechild = ogreskel->getBone(bone->szName);
			Bone* ogreparent = ogreskel->getBone(bone->szParentName);

			if (ogrechild == 0)
			{
				continue;
			}
			if (ogreparent == 0)
			{
				continue;
			}
			// Make child
			ogreparent->addChild(ogrechild);
		}


	}

	// Create the Animation(s)
	doExportAnimations(pModel, ogreskel);

	// Create skeleton serializer & export
	SkeletonSerializer serializer;
	serializer.exportSkeleton(ogreskel, szFile);

	ogreMesh->_notifySkeleton(ogreskel);

	return ogreskel;
*/
	delete ogreskel;
	return NULL;
}

#define POSITION_BINDING 0
#define NORMAL_BINDING 1
#define TEXCOORD_BINDING 2

VertexData *Lwo2MeshWriter::setupVertexData(unsigned short vertexCount, VertexData *oldVertexData, bool deleteOldVertexData)
{
	VertexData *vertexData = new VertexData();

	if (oldVertexData)
	{
        // Basic vertex info
        vertexData->vertexStart = oldVertexData->vertexStart;
		vertexData->vertexCount = oldVertexData->vertexCount + vertexCount;

		const VertexBufferBinding::VertexBufferBindingMap bindings = oldVertexData->vertexBufferBinding->getBindings();
		VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend;
		vbend = bindings.end();

		for (vbi = bindings.begin(); vbi != vbend; ++vbi)
		{
			HardwareVertexBufferSharedPtr srcbuf = vbi->second;
			// create new buffer with the same settings
			HardwareVertexBufferSharedPtr dstBuf = 
				HardwareBufferManager::getSingleton().createVertexBuffer(
					srcbuf->getVertexSize(), srcbuf->getNumVertices() + vertexCount, srcbuf->getUsage(), srcbuf->isSystemMemory());

			// copy data
			dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true);

			// Copy binding
			vertexData->vertexBufferBinding->setBinding(vbi->first, dstBuf);
		}

        // Copy elements
        const VertexDeclaration::VertexElementList elems = oldVertexData->vertexDeclaration->getElements();
        VertexDeclaration::VertexElementList::const_iterator ei, eiend;
        eiend = elems.end();
        for (ei = elems.begin(); ei != eiend; ++ei)
        {
            vertexData->vertexDeclaration->addElement(
                ei->getSource(),
                ei->getOffset(),
                ei->getType(),
                ei->getSemantic(),
                ei->getIndex() );
        }
		if (deleteOldVertexData) delete oldVertexData;
	}
	else
	{
		vertexData->vertexCount = vertexCount;
		
		VertexBufferBinding* bind = vertexData->vertexBufferBinding;
		VertexDeclaration* decl = vertexData->vertexDeclaration;
		
		decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
		HardwareVertexBufferSharedPtr pbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POSITION_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
		bind->setBinding(POSITION_BINDING, pbuf);
		
		decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);
		HardwareVertexBufferSharedPtr nbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
		bind->setBinding(NORMAL_BINDING, nbuf);
		
		decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
		HardwareVertexBufferSharedPtr tbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
		bind->setBinding(TEXCOORD_BINDING, tbuf);
	}	
	return vertexData;
}

void Lwo2MeshWriter::copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints)
{
	for (unsigned int i = 0; i < sourcepoints.size(); i++)
	{
		lwPoint *point = sourcepoints[i];
		

⌨️ 快捷键说明

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