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

📄 lwo2mesh.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "vector3.h"
#include "lwo2mesh.h"
#include "Ogre.h"
#include "OgreMesh.h"
#include "OgreStringConverter.h"
#include "OgreDefaultHardwareBufferManager.h"

#define POLYLIMIT 0x5555
#define POINTLIMIT 0x5555

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

void Lwo2MeshWriter::doExportMaterials()
{
	char
		drive[ _MAX_DRIVE ],
		dir[ _MAX_DIR ],
		node[ _MAX_FNAME ],
		ext[ _MAX_EXT ],
		texname [128];
	
	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]
			);
			
			ogreMat->setSpecular
			(
				surface->specularity.val * surface->color.rgb[0],
				surface->specularity.val * surface->color.rgb[1],
				surface->specularity.val * surface->color.rgb[2]
			);
			
			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];
		
		for (unsigned int j = 0; j < point->polygons.size(); j++)
		{
			lwPolygon *polygon = point->polygons[j];
			if (polygon->type == polygontype)
				if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
				{
					destpoints.push_back(point);
					break;
				}
		}
	}
}

void Lwo2MeshWriter::copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons)
{
	for (unsigned int i = 0; i < sourcepolygons.size(); i++)
	{
		lwPolygon *polygon = sourcepolygons[i];
		if (polygon->type == polygontype)
			if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
				destpolygons.push_back(polygon);
	}
}

void Lwo2MeshWriter::copyDataToVertexData(vpoints &points,
										vpolygons &polygons,
										vvmaps &vmaps,
										IndexData *indexData,
										VertexData *vertexData,
										unsigned short vertexDataOffset)
{
	lwVMap *vmap = 0;
	unsigned int ni;
	
	HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
	HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
	HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
	HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;

	Real* pPos = static_cast<Real*>(pbuf->lock(HardwareBuffer::HBL_DISCARD));
	Real* pNor = static_cast<Real*>(nbuf->lock(HardwareBuffer::HBL_DISCARD));
	Real* pTex = static_cast<Real*>(tbuf->lock(HardwareBuffer::HBL_DISCARD));
	unsigned short *pIdx = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));

	for (unsigned int p = 0; p < polygons.size(); p++)
	{
		lwPolygon *polygon = polygons[p];
		
		if (polygon->vertices.size() != 3) continue; // only copy triangles;

		for (unsigned int v = 0; v < polygon->vertices.size(); v++)
		{
			lwVertex *vertex = polygon->vertices[v];
			lwPoint *point = vertex->point;
			unsigned short i = getPointIndex(point, points);

			pIdx[p*3 + v] = vertexDataOffset + i;
			
			ni = (vertexDataOffset + i) * 3;

⌨️ 快捷键说明

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