Пример #1
0
void MeshBuilder::end()
{
    assert(!m_bIsSharedVertices && !m_currentSubMesh.strName.empty() && "You must call begin() before you call end()");
    assert(!m_currentSubMesh.bUseSharedVertices || m_mesh->sharedVertexData);

    // Declarations
    std::map<unsigned short, std::vector<tElement> >::iterator  iterSource, iterSourceEnd;
    std::vector<tVertex>::iterator                              iterVertex, iterVertexEnd;
    HardwareVertexBufferSharedPtr                               vbuffer;
    VertexData*                                                 pVertexData;

    // If a temporary vertex is pending, add it to the list
    if (m_bTempVertexPending)
        copyTempVertexToBuffer();

    m_bFirstVertex          = false;
    m_bAutomaticDeclaration = false;
    m_bIsSharedVertices     = false;

    // Create the submesh
    SubMesh* pSubMesh = m_mesh->createSubMesh(m_currentSubMesh.strName);
    pSubMesh->setMaterialName(m_currentSubMesh.strMaterial);
    pSubMesh->useSharedVertices = m_currentSubMesh.bUseSharedVertices;
    pSubMesh->operationType = m_currentSubMesh.opType;

    // Initializes the vertex declaration if necessary
    if (!m_currentSubMesh.bUseSharedVertices)
    {
        pSubMesh->vertexData = createVertexData();
        pVertexData = pSubMesh->vertexData;
    }
    else
    {
        pVertexData = m_mesh->sharedVertexData;
    }

    // Add the vertices into their buffers
    VertexBufferBinding::VertexBufferBindingMap bindings = pVertexData->vertexBufferBinding->getBindings();
    for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end();
        iterSource != iterSourceEnd; ++iterSource)
    {
        unsigned int vertexIndex = 0;

        for (iterVertex = m_currentSubMesh.vertices.begin(), iterVertexEnd = m_currentSubMesh.vertices.end();
            iterVertex != iterVertexEnd; ++iterVertex)
        {
            if ((iterVertex->blendingDim > 0) && !m_mesh->getSkeletonName().empty())
            {
                VertexBoneAssignment ass;
                ass.vertexIndex = vertexIndex;

                for (unsigned int i = 0; i < iterVertex->blendingDim; ++i)
                {
                    ass.boneIndex   = iterVertex->blendingIndices[i];
                    ass.weight      = iterVertex->blendingWeights[i];
                    pSubMesh->addBoneAssignment(ass);
                }
            }

            ++vertexIndex;
        }
    }


    // Add the indices into their buffer
    pSubMesh->indexData->indexCount = m_currentSubMesh.indices.size();
    pSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
                                                    HardwareIndexBuffer::IT_16BIT, m_currentSubMesh.indices.size(),
                                                    m_currentSubMesh.indexBufferInfo.usage,
                                                    m_currentSubMesh.indexBufferInfo.bUseShadowBuffer);
    pSubMesh->indexData->indexBuffer->writeData(0, m_currentSubMesh.indices.size() * sizeof(unsigned short),
                                                &m_currentSubMesh.indices[0]);


    // Update the AABB and the radius of the mesh
    m_mesh->_setBounds(toOgre(m_AABB));
    m_mesh->_setBoundingSphereRadius(m_radius);


    // Reset the internal state
    m_currentSubMesh.strName            = "";
    m_currentSubMesh.strMaterial        = "";
    m_currentSubMesh.bUseSharedVertices = false;

    m_currentSubMesh.indexBufferInfo.usage              = HardwareBuffer::HBU_STATIC_WRITE_ONLY;
    m_currentSubMesh.indexBufferInfo.bUseShadowBuffer   = false;

    m_currentSubMesh.verticesElements.clear();
    m_currentSubMesh.vertexBufferInfos.clear();
    m_currentSubMesh.vertices.clear();
    m_currentSubMesh.indices.clear();
}
Пример #2
0
	MeshPtr MeshMergeTool::merge(const Ogre::String& name, const Ogre::String& resourceGroupName)
	{
		print("Baking: New Mesh started", V_HIGH);

		MeshPtr mp = MeshManager::getSingleton().createManual(name, resourceGroupName);

		if (!mBaseSkeleton.isNull())
		{
			mp->setSkeletonName(mBaseSkeleton->getName());
		}

		AxisAlignedBox totalBounds = AxisAlignedBox();
		for (std::vector<Ogre::MeshPtr>::iterator it = mMeshes.begin(); it != mMeshes.end(); ++it)
		{
			print("Baking: adding submeshes for " + (*it)->getName(), V_HIGH);

			// insert all submeshes
			for (Ogre::ushort sid = 0; sid < (*it)->getNumSubMeshes(); ++sid)
			{
				SubMesh* sub = (*it)->getSubMesh(sid);
				const String name = findSubmeshName((*it), sid);

				// create submesh with correct name
				SubMesh* newsub;
				if (name.length() == 0)
				{
					newsub = mp->createSubMesh();
				}
				else
				{
					/// @todo check if a submesh with this name has been created before
					newsub = mp->createSubMesh(name);
				}

				newsub->useSharedVertices = sub->useSharedVertices;

				// add index
				newsub->indexData = sub->indexData->clone();

				// add geometry
				if (!newsub->useSharedVertices)
				{
					newsub->vertexData = sub->vertexData->clone();

					if (!mBaseSkeleton.isNull())
					{
						// build bone assignments
						SubMesh::BoneAssignmentIterator bit = sub->getBoneAssignmentIterator();
						while (bit.hasMoreElements())
						{
							VertexBoneAssignment vba = bit.getNext();
							newsub->addBoneAssignment(vba);
						}
					}
				}

				newsub->setMaterialName(sub->getMaterialName());

				// Add vertex animations for this submesh
				Animation *anim = 0;
				for (unsigned short i = 0; i < (*it)->getNumAnimations(); ++i)
				{
					anim = (*it)->getAnimation(i);

					// get or create the animation for the new mesh
					Animation *newanim;
					if (mp->hasAnimation(anim->getName()))
					{
						newanim = mp->getAnimation(anim->getName());
					}
					else
					{
						newanim = mp->createAnimation(anim->getName(), anim->getLength());
					}

					print("Baking: adding vertex animation "
						+ anim->getName() + " for " + (*it)->getName(), V_HIGH);

					Animation::VertexTrackIterator vti=anim->getVertexTrackIterator();
					while (vti.hasMoreElements())
					{
						VertexAnimationTrack *vt = vti.getNext();

						// handle=0 targets the main mesh, handle i (where i>0) targets submesh i-1.
						// In this case there are only submeshes so index 0 will not be used.
						unsigned short handle = mp->getNumSubMeshes();
						VertexAnimationTrack* newvt = newanim->createVertexTrack(
								handle,
								vt->getAssociatedVertexData()->clone(),
								vt->getAnimationType());
						for (int keyFrameIndex = 0; keyFrameIndex < vt->getNumKeyFrames();
							++keyFrameIndex)
						{
							switch (vt->getAnimationType())
							{
								case VAT_MORPH:
								{
									// copy the keyframe vertex buffer
									VertexMorphKeyFrame *kf =
										vt->getVertexMorphKeyFrame(keyFrameIndex);
									VertexMorphKeyFrame *newkf =
										newvt->createVertexMorphKeyFrame(kf->getTime());
									// This creates a ref to the buffer in the original model
									// so don't delete it until the export is completed.
									newkf->setVertexBuffer(kf->getVertexBuffer());
									break;
								}
								case VAT_POSE:
								{
									/// @todo implement pose amination merge
									break;
								}
								case VAT_NONE:
								default:
								{
									break;
								}
							}
						}
					}
				}

				print("Baking: adding submesh '" +
					name + "'  with material " + sub->getMaterialName(), V_HIGH);
			}

			// sharedvertices
			if ((*it)->sharedVertexData)
			{
				/// @todo merge with existing sharedVertexData
				if (!mp->sharedVertexData)
				{
					mp->sharedVertexData = (*it)->sharedVertexData->clone();
				}

				if (!mBaseSkeleton.isNull())
				{
					Mesh::BoneAssignmentIterator bit = (*it)->getBoneAssignmentIterator();
					while (bit.hasMoreElements())
					{
						VertexBoneAssignment vba = bit.getNext();
						mp->addBoneAssignment(vba);
					}
				}
			}

			print("Baking: adding bounds for " + (*it)->getName(), V_HIGH);

			// add bounds
			totalBounds.merge((*it)->getBounds());
		}
		mp->_setBounds(totalBounds);

		/// @todo merge submeshes with same material

		/// @todo add parameters
		mp->buildEdgeList();

		print("Baking: Finished", V_HIGH);

		reset();

		return mp;
	}
Пример #3
0
    MeshPtr MergeMesh::bake()
    {    
        log( 
             "Baking: New Mesh started" );

        MeshPtr mp = MeshManager::getSingleton().
            createManual( "mergedMesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
        mp->setSkeletonName( m_BaseSkeleton->getName() );

        AxisAlignedBox totalBounds = AxisAlignedBox();
        for( std::vector< Ogre::MeshPtr >::iterator it = m_Meshes.begin();
             it != m_Meshes.end(); ++it )
        {   
            log( 
                "Baking: adding submeshes for " + (*it)->getName() );

            // insert all submeshes
            for( Ogre::ushort sid = 0; sid < (*it)->getNumSubMeshes(); ++sid )
            {
                SubMesh* sub = (*it)->getSubMesh( sid );
                const String name = findSubmeshName( (*it), sid );                
                
                // create submesh with correct name                
                SubMesh* newsub;
                if( name.length() == 0 )
                    newsub = mp->createSubMesh(  );
                else 
                /// @todo check if a submesh with this name has been created before
                    newsub = mp->createSubMesh( name );   

                newsub->useSharedVertices = sub->useSharedVertices;

                // add index
                newsub->indexData = sub->indexData->clone();

                // add geometry
                if( !newsub->useSharedVertices )
                {
                    newsub->vertexData = sub->vertexData->clone();
                
                    // build bone assignments
                    SubMesh::BoneAssignmentIterator bit = sub->getBoneAssignmentIterator();
                    while (bit.hasMoreElements())
                    {
                        VertexBoneAssignment vba = bit.getNext();
                        newsub->addBoneAssignment(vba);
                    }
                }

                newsub->setMaterialName( sub->getMaterialName() );

                log("Baking: adding submesh '" + name + "'  with material " + sub->getMaterialName());
            } 

            // sharedvertices
            if ((*it)->sharedVertexData)
            {
                /// @todo merge with existing sharedVertexData
                if (!mp->sharedVertexData)
				{
					mp->sharedVertexData = (*it)->sharedVertexData->clone();
				}

                Mesh::BoneAssignmentIterator bit = (*it)->getBoneAssignmentIterator();
                while (bit.hasMoreElements())
                {
                    VertexBoneAssignment vba = bit.getNext();
                    mp->addBoneAssignment(vba);
                }
            }

            log("Baking: adding bounds for " + (*it)->getName());

            // add bounds
            totalBounds.merge((*it)->getBounds());
        }           
        mp->_setBounds( totalBounds );

        /// @todo merge submeshes with same material


        /// @todo add parameters
        mp->buildEdgeList();

        log( 
            "Baking: Finished" );

        return mp;
	}
Пример #4
0
    //-----------------------------------------------------------------------
    void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh)
    {
        // Retrieve data to copy bone assignments
        const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments();
        Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin();
        Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end();
        size_t curVertexOffset = 0;

        // Access shared vertices
        VertexData* sharedVertexData = mesh->sharedVertexData;

        for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++)
        {
            SubMesh *subMesh = mesh->getSubMesh(subMeshIdx);

            IndexData *indexData = subMesh->indexData;
            HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType();
            IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices<uint16>(indexData) :
                                                                                 getUsedIndices<uint32>(indexData);


            VertexData *newVertexData = new VertexData();
            newVertexData->vertexCount = indicesMap.size();
            newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone();

            for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) 
            {
                HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx);
                size_t vertexSize = sharedVertexBuffer->getVertexSize();                

                HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer
                    (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer());

                uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY);
                uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL);

                IndicesMap::iterator indIt = indicesMap.begin();
                IndicesMap::iterator endIndIt = indicesMap.end();
                for (; indIt != endIndIt; ++indIt)
                {
                    memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize);
                }

                sharedVertexBuffer->unlock();
                newVertexBuffer->unlock();

                newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer);
            }

            if (idxType == HardwareIndexBuffer::IT_16BIT)
            {
                copyIndexBuffer<uint16>(indexData, indicesMap);
            }
            else
            {
                copyIndexBuffer<uint32>(indexData, indicesMap);
            }

            // Store new attributes
            subMesh->useSharedVertices = false;
            subMesh->vertexData = newVertexData;

            // Transfer bone assignments to the submesh
            size_t offset = curVertexOffset + newVertexData->vertexCount;
            for (; it != end; ++it)
            {
                size_t vertexIdx = (*it).first;
                if (vertexIdx > offset)
                    break;

                VertexBoneAssignment boneAssignment = (*it).second;
                boneAssignment.vertexIndex = static_cast<unsigned int>(boneAssignment.vertexIndex - curVertexOffset);
                subMesh->addBoneAssignment(boneAssignment);
            }
            curVertexOffset = newVertexData->vertexCount + 1;
        }

        // Release shared vertex data
        delete mesh->sharedVertexData;
        mesh->sharedVertexData = NULL;
        mesh->clearBoneAssignments();
    }
Пример #5
0
	//---------------------------------------------------------------------
	void OptimiseTool::processMesh(Ogre::MeshPtr mesh)
	{
		bool rebuildEdgeList = false;
		// Shared geometry
		if (mesh->sharedVertexData)
		{
			print("Optimising mesh shared vertex data...");
			setTargetVertexData(mesh->sharedVertexData);

			for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
			{
				SubMesh* sm = mesh->getSubMesh(i);
				if (sm->useSharedVertices)
				{
					addIndexData(sm->indexData);
				}
			}

			if (optimiseGeometry())
			{
				if (mesh->getSkeletonName() != StringUtil::BLANK)
				{
					print("    fixing bone assignments...");
					Mesh::BoneAssignmentIterator currentIt = mesh->getBoneAssignmentIterator();
					Mesh::VertexBoneAssignmentList newList =
						getAdjustedBoneAssignments(currentIt);
					mesh->clearBoneAssignments();
					for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
						bi != newList.end(); ++bi)
					{
						mesh->addBoneAssignment(bi->second);
					}

				}

				for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
				{
					SubMesh* sm = mesh->getSubMesh(i);
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}
					if (sm->useSharedVertices)
					{
						fixLOD(sm->mLodFaceList);
					}
				}
				rebuildEdgeList = true;

			}
		}

		// Dedicated geometry
		for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
		{
			SubMesh* sm = mesh->getSubMesh(i);
			if (!sm->useSharedVertices)
			{
				print("Optimising submesh " +
					StringConverter::toString(i) + " dedicated vertex data ");
				setTargetVertexData(sm->vertexData);
				addIndexData(sm->indexData);
				if (optimiseGeometry())
				{
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}

					fixLOD(sm->mLodFaceList);
					rebuildEdgeList = true;
				}
			}
		}

		if (rebuildEdgeList && mesh->isEdgeListBuilt())
		{
			// force rebuild of edge list
			mesh->freeEdgeList();
			mesh->buildEdgeList();
		}


	}
Пример #6
0
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
// mesh.
void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments)
{
    //  cout << "s:" << shape << "\n";
    NiTriShapeData *data = shape->data.getPtr();
    SubMesh *sub = mesh->createSubMesh(shape->name.toString());

    int nextBuf = 0;

    // This function is just one long stream of Ogre-barf, but it works
    // great.

    // Add vertices
    int numVerts = data->vertices.length / 3;
    sub->vertexData = new VertexData();
    sub->vertexData->vertexCount = numVerts;
    sub->useSharedVertices = false;

    VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
    decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);

    HardwareVertexBufferSharedPtr vbuf =
        HardwareBufferManager::getSingleton().createVertexBuffer(
            VertexElement::getTypeSize(VET_FLOAT3),
            numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);

    if(flip)
	{
		float *datamod = new float[data->vertices.length];
		//std::cout << "Shape" << shape->name.toString() << "\n";
		for(int i = 0; i < numVerts; i++)
		{
			int index = i * 3;
			const float *pos = data->vertices.ptr + index;
		    Ogre::Vector3 original = Ogre::Vector3(*pos  ,*(pos+1), *(pos+2));
			original = mTransform * original;
			mBoundingBox.merge(original);
			datamod[index] = original.x;
			datamod[index+1] = original.y;
			datamod[index+2] = original.z;
		}
        vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false);
        delete [] datamod;
	}
	else
	{
		vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false);
	}


    VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
    bind->setBinding(nextBuf++, vbuf);

    if (data->normals.length)
    {
        decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                   VertexElement::getTypeSize(VET_FLOAT3),
                   numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		if(flip)
		{
			Quaternion rotation = mTransform.extractQuaternion();
			rotation.normalise();

			float *datamod = new float[data->normals.length];
			for(int i = 0; i < numVerts; i++)
		    {
			    int index = i * 3;
			    const float *pos = data->normals.ptr + index;
		        Ogre::Vector3 original = Ogre::Vector3(*pos  ,*(pos+1), *(pos+2));
				original = rotation * original;
				if (mNormaliseNormals)
			    {
                    original.normalise();
				}


			    datamod[index] = original.x;
			    datamod[index+1] = original.y;
			    datamod[index+2] = original.z;
		    }
			vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false);
            delete [] datamod;
		}
		else
		{
            vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false);
		}
        bind->setBinding(nextBuf++, vbuf);
    }

    
    // Vertex colors
    if (data->colors.length)
    {
        const float *colors = data->colors.ptr;
        RenderSystem* rs = Root::getSingleton().getRenderSystem();
        std::vector<RGBA> colorsRGB(numVerts);
        RGBA *pColour = &colorsRGB.front();
        for (int i=0; i<numVerts; i++)
        {
            rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2],
                                               colors[3]),pColour++);
            colors += 4;
        }
        decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE);
        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                   VertexElement::getTypeSize(VET_COLOUR),
                   numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true);
        bind->setBinding(nextBuf++, vbuf);
    }

     if (data->uvlist.length)
    {

        decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
        vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                   VertexElement::getTypeSize(VET_FLOAT2),
                   numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false);

		if(flip)
		{
		    float *datamod = new float[data->uvlist.length];

		    for(unsigned int i = 0; i < data->uvlist.length; i+=2){
			    float x = *(data->uvlist.ptr + i);

			    float y = *(data->uvlist.ptr + i + 1);

			    datamod[i] =x;
				datamod[i + 1] =y;
		    }
			vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false);
            delete [] datamod;
		}
		else
			vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false);
        bind->setBinding(nextBuf++, vbuf);
    }

   // Triangle faces - The total number of triangle points
    int numFaces = data->triangles.length;

    if (numFaces)
    {

		sub->indexData->indexCount = numFaces;
        sub->indexData->indexStart = 0;
        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
                                            createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
                                                              numFaces,
                                                              HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);

		if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){

			sub->indexData->indexBuffer = ibuf;

			uint16 *datamod = new uint16[numFaces];
			int index = 0;
			for (size_t i = 0; i < sub->indexData->indexCount; i+=3)
			{

			     const short *pos = data->triangles.ptr + index;
				uint16 i0 = (uint16) *(pos+0);
				uint16 i1 = (uint16) *(pos+1);
				uint16 i2 = (uint16) *(pos+2);

				//std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n";


				datamod[index] = i2;
				datamod[index+1] = i1;
				datamod[index+2] = i0;

				index += 3;
			}

            ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false);
            delete [] datamod;

		}
		else
            ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false);
        sub->indexData->indexBuffer = ibuf;
    }

    // Set material if one was given
    if (!material.empty()) sub->setMaterialName(material);

    //add vertex bone assignments

    for (std::list<VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin();
        it != vertexBoneAssignments.end(); it++)
    {
            sub->addBoneAssignment(*it);
    }
    if(mSkel.isNull())
       needBoneAssignments.push_back(sub);
}