Exemple #1
0
void ModelConverter::WriteSubMesh( DiSubMesh* subMod, const Ogre::SubMesh* s )
{
	switch(s->operationType)
	{
	case RenderOperation::OT_LINE_LIST:
		subMod->SetPrimitiveType(D3DPT_LINELIST);
		break;
	case RenderOperation::OT_LINE_STRIP:
		subMod->SetPrimitiveType(D3DPT_LINESTRIP);
		break;
	case RenderOperation::OT_POINT_LIST:
		subMod->SetPrimitiveType(D3DPT_POINTLIST);
		break;
	case RenderOperation::OT_TRIANGLE_FAN:
		subMod->SetPrimitiveType(D3DPT_TRIANGLEFAN);
		break;
	case RenderOperation::OT_TRIANGLE_LIST:
		subMod->SetPrimitiveType(PT_TRIANGLELIST);
		break;
	case RenderOperation::OT_TRIANGLE_STRIP:
		subMod->SetPrimitiveType(D3DPT_TRIANGLESTRIP);
		break;
	}

	VertexData* vertexData = nullptr;
	if (mMesh->sharedVertexData)
	{
		vertexData = mMesh->sharedVertexData;
	}
	else
	{
		vertexData = s->vertexData;
	}

	int numFaces = 0;
	switch(s->operationType)
	{
	case RenderOperation::OT_TRIANGLE_LIST:
		// triangle list
		numFaces = s->indexData->indexCount / 3;

		break;
	case RenderOperation::OT_LINE_LIST:
		numFaces = s->indexData->indexCount / 2;

		break;
	case RenderOperation::OT_TRIANGLE_FAN:
	case RenderOperation::OT_TRIANGLE_STRIP:
		// triangle fan or triangle strip
		numFaces = s->indexData->indexCount - 2;

		break;
	default:
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
			"Unsupported render operation type", 
			__FUNCTION__);
	}

	subMod->SetPrimitiveCount(numFaces);
	subMod->SetVerticeNum(vertexData->vertexCount);

	// material name
	DiString matName;
	matName.Format("%s_%d.mtl",subMod->GetParentMesh()->GetName().c_str(),subMod->GetIndex());
	subMod->SetMaterialName(matName);

	bool use32BitIndexes = (!s->indexData->indexBuffer.isNull() && 
		s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT);

	// Write each face in turn
	unsigned int* pInt = 0;
	unsigned short* pShort = 0;
	HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer;

	// index data
	if (use32BitIndexes)
	{
		pInt = static_cast<unsigned int*>(
			ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); 
	}
	else
	{
		pShort = static_cast<unsigned short*>(
			ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); 
	}

	void* indata = subMod->CreateIndexData(s->indexData->indexCount,use32BitIndexes?TRUE:FALSE);
	if (use32BitIndexes)
	{
		memcpy(indata,pInt,sizeof(unsigned int)*s->indexData->indexCount);
	}
	else
	{
		memcpy(indata,pShort,sizeof(unsigned short)*s->indexData->indexCount);
	}

	ibuf->unlock();

	// vertex declaration
	VertexDeclaration* decl = vertexData->vertexDeclaration;
	VertexBufferBinding* bind = vertexData->vertexBufferBinding;

	VertexBufferBinding::VertexBufferBindingMap::const_iterator b, bend;
	bend = bind->getBindings().end();
	// iterate over buffers
	int bindCount = 0;
	for(b = bind->getBindings().begin(); b != bend; ++b,++bindCount)
	{
		const HardwareVertexBufferSharedPtr vbuf = b->second;
		unsigned short bufferIdx = b->first;
		// get all the elements that relate to this buffer			
		VertexDeclaration::VertexElementList elems = decl->findElementsBySource(bufferIdx);
		VertexDeclaration::VertexElementList::iterator i, iend;
		iend = elems.end();

		unsigned short nuDemiureCoords = 0;
		for (i = elems.begin(); i != iend; ++i)
		{
			VertexElement& elem = *i;

			D3DDECLTYPE type = ConverteVertType(elem.getType());
			D3DDECLUSAGE usage;
			bool texcoord = false;
			switch(elem.getSemantic())
			{
			case VES_POSITION:
				usage = D3DDECLUSAGE_POSITION;
				break;
			case VES_NORMAL:
				usage = D3DDECLUSAGE_NORMAL;
				break;
			case VES_TANGENT:
				usage = D3DDECLUSAGE_TANGENT;
				break;
			case VES_BINORMAL:
				usage = D3DDECLUSAGE_BINORMAL;
				break;
			case VES_DIFFUSE:
			case VES_SPECULAR:
				usage = D3DDECLUSAGE_COLOR;
				break;
			case VES_TEXTURE_COORDINATES:
				usage = D3DDECLUSAGE_TEXCOORD;
				++nuDemiureCoords;
				texcoord = true;
				break;
			default:
				DI_ERROR("Unsupported semantic");
			}

			subMod->GetVertexElements().AddElement(bindCount,type,usage,texcoord?nuDemiureCoords-1:0);
		}

		int stride = subMod->GetVertexElements().GetStreamElementsSize(bindCount);
		void* vertData = subMod->CreateSourceData(bindCount,vertexData->vertexCount,stride);

		unsigned char* pVert = static_cast<unsigned char*>(
			vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
		memcpy(vertData,pVert,vertexData->vertexCount*stride);
		vbuf->unlock();
	}

	// vertex weight
	if (mMesh->hasSkeleton())
	{
		LogManager::getSingleton().logMessage("Exporting dedicated geometry bone assignments...");

		if(const_cast<SubMesh*>(s)->getBoneAssignments().empty())
		{
			SubMesh::BoneAssignmentIterator bi = mMesh->getBoneAssignmentIterator();
			while (bi.hasMoreElements())
			{
				const VertexBoneAssignment& assign = bi.getNext();
				if (assign.weight > 0.0f)
				{
					subMod->AddWeight(assign.vertexIndex,assign.boneIndex,assign.weight);
				}
			}
		}
		else
		{
			SubMesh::BoneAssignmentIterator bi = (const_cast<SubMesh*>(s))->getBoneAssignmentIterator();
			while (bi.hasMoreElements())
			{
				const VertexBoneAssignment& assign = bi.getNext();
				if (assign.weight > 0.0f)
				{
					subMod->AddWeight(assign.vertexIndex,assign.boneIndex,assign.weight);
				}
			}
		}
		
		subMod->RationaliseBoneWeights();
	}
}