//---------------------------------------------------------------------
	void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits)
	{
		if (!vertexSplits.empty())
		{
			// ok, need to increase the vertex buffer size, and alter some indexes

			// vertex buffers first
			VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding();
			const VertexBufferBinding::VertexBufferBindingMap& bindmap = 
				mVData->vertexBufferBinding->getBindings();
			for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = 
				bindmap.begin(); i != bindmap.end(); ++i)
			{
				HardwareVertexBufferSharedPtr srcbuf = i->second;
				// Derive vertex count from buffer not vertex data, in case using
				// the vertexStart option in vertex data
				size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size();
				// Create new buffer & bind
				HardwareVertexBufferSharedPtr newBuf = 
					HardwareBufferManager::getSingleton().createVertexBuffer(
					srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), 
					srcbuf->hasShadowBuffer());
				newBindings->setBinding(i->first, newBuf);

				// Copy existing contents (again, entire buffer, not just elements referenced)
				newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true);

				// Split vertices, read / write from new buffer
				char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));
				for (VertexSplits::iterator spliti = vertexSplits.begin(); 
					spliti != vertexSplits.end(); ++spliti)
				{
					const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize();
					char* pDstBase = pBase + spliti->second * newBuf->getVertexSize();
					memcpy(pDstBase, pSrcBase, newBuf->getVertexSize());
				}
				newBuf->unlock();

			}

			// Update vertex data
			// Increase vertex count according to num splits
			mVData->vertexCount += vertexSplits.size();
			// Flip bindings over to new buffers (old buffers released)
			HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding);
			mVData->vertexBufferBinding = newBindings;
			
		}

	}
Example #2
0
//--------------------------------------------------------------------------
void MeshLodTests::addProfile(LodConfig& config)
{
    // Get the first two vertices and put the edge into the profile
    // It doesn't matter if there is no such edge, because edges are removed and created dynamically.
    // The vertex positions should exist or you get an assert.
    VertexData* vertexData = config.mesh->getSubMesh(0)->vertexData;
    const VertexElement* elemPos = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
    HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(elemPos->getSource());
    assert(vbuf->getNumVertices() > 2);
    unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
    float* pFloat;
    elemPos->baseVertexPointerToElement(vertex, &pFloat);
    ProfiledEdge edge;
    edge.src.x = *pFloat++;
    edge.src.y = *pFloat++;
    edge.src.z = *pFloat;
    vertex += vbuf->getVertexSize();
    elemPos->baseVertexPointerToElement(vertex, &pFloat);
    edge.dst.x = *pFloat++;
    edge.dst.y = *pFloat++;
    edge.dst.z = *pFloat;
    edge.cost = LodData::NEVER_COLLAPSE_COST;
    config.advanced.profile.push_back(edge);
    vbuf->unlock();
}
 //-----------------------------------------------------------------------
 HardwareVertexBufferSharedPtr 
 HardwareBufferManagerBase::makeBufferCopy(
     const HardwareVertexBufferSharedPtr& source,
     HardwareBuffer::Usage usage, bool useShadowBuffer)
 {
     return this->createVertexBuffer(
         source->getVertexSize(), 
         source->getNumVertices(),
         usage, useShadowBuffer);
 }
Example #4
0
void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
{
    // Get the vertex colour buffer of this mesh
    const Ogre::VertexElement* ves_diffuse = ent->getMesh()->getSubMesh(0)->vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_DIFFUSE );
    HardwareVertexBufferSharedPtr colourBuffer = ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource());

    // Lock
    void* pData = colourBuffer->lock(HardwareBuffer::HBL_NORMAL);

    // Iterate over all vertices
    int vertex_size = colourBuffer->getVertexSize();
    float * currentVertex = NULL;
    for (unsigned int i=0; i<colourBuffer->getNumVertices(); ++i)
    {
        // Get a pointer to the vertex colour
        ves_diffuse->baseVertexPointerToElement( pData, &currentVertex );

        unsigned char alpha=0;
        if (meshType == 0) alpha = i%2 ? 0 : 255; // this is a cylinder, so every second vertex belongs to the bottom-most row
        else if (meshType == 1)
        {
            if (i>= 49 && i <= 64) alpha = 0; // bottom-most row
            else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
            else alpha = 255;
        }

        uint8 tmpR = static_cast<uint8>(255);
        uint8 tmpG = static_cast<uint8>(255);
        uint8 tmpB = static_cast<uint8>(255);
        uint8 tmpA = static_cast<uint8>(alpha);

        // This does not matter since R and B are always 1.
        /*VertexElementType format = Root::getSingleton().getRenderSystem()->getColourVertexElementType();
        switch (format)
        {
        case VET_COLOUR_ARGB:
            std::swap(tmpR, tmpB);
            break;
        case VET_COLOUR_ABGR:
            break;
        default:
            break;
        }*/

        // Modify
        *((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);

        // Move to the next vertex
        pData = static_cast<unsigned char *> (pData) + vertex_size;
    }

    // Unlock
    ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
}
void NxTriangles::SetTextureCoordinates( const float * Coordinates )
{
 
	HardwareVertexBufferSharedPtr cbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(2);

	 
	cbuf->writeData(0, cbuf->getNumVertices() * sizeof(float) * (mUVW ? 3 : 2), Coordinates, true );

 

}
Example #6
0
void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
{
    // Get the vertex colour buffer of this mesh
    const Ogre::VertexElement* ves_diffuse = ent->getMesh()->getSubMesh(0)->vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_DIFFUSE );
    HardwareVertexBufferSharedPtr colourBuffer = ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource());

    // Lock
    void* pData = colourBuffer->lock(HardwareBuffer::HBL_NORMAL);

    // Iterate over all vertices
    int vertex_size = colourBuffer->getVertexSize();
    float * currentVertex = NULL;
    for (unsigned int i=0; i<colourBuffer->getNumVertices(); ++i)
    {
        // Get a pointer to the vertex colour
        ves_diffuse->baseVertexPointerToElement( pData, &currentVertex );

        unsigned char alpha=0;
        if (meshType == 0) alpha = i%2 ? 0 : 255; // this is a cylinder, so every second vertex belongs to the bottom-most row
        else if (meshType == 1)
        {
            if (i>= 49 && i <= 64) alpha = 0; // bottom-most row
            else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
            else alpha = 255;
        }
        // NB we would have to swap R and B depending on rendersystem specific VertexElementType, but doesn't matter since they are both 1
        uint8 tmpR = static_cast<uint8>(255);
        uint8 tmpG = static_cast<uint8>(255);
        uint8 tmpB = static_cast<uint8>(255);
        uint8 tmpA = static_cast<uint8>(alpha);

        // Modify
        *((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);

        // Move to the next vertex
        pData = static_cast<unsigned char *> (pData) + vertex_size;
    }

    // Unlock
    ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
}
Example #7
0
void OgreNewtonMesh::ParseEntity (MeshPtr mesh, const Matrix4& matrix)
{
	//find number of sub-meshes
	unsigned short sub = mesh->getNumSubMeshes();

	for (unsigned short cs = 0; cs < sub; cs++) {

		SubMesh* const sub_mesh = mesh->getSubMesh(cs);

		//vertex data!
		VertexData* v_data;

		if (sub_mesh->useSharedVertices) {
			v_data = mesh->sharedVertexData;
		} else {
			v_data = sub_mesh->vertexData;
		}

		//let's find more information about the Vertices...
		VertexDeclaration* const v_decl = v_data->vertexDeclaration;

		const VertexElement* const vertexElem = v_decl->findElementBySemantic(VES_POSITION);
		HardwareVertexBufferSharedPtr vertexPtr = v_data->vertexBufferBinding->getBuffer(vertexElem->getSource());
		dNewtonScopeBuffer<Vector3> points(vertexPtr->getNumVertices());
		{
			int size = vertexPtr->getVertexSize();
			int offset = vertexElem->getOffset() / sizeof (float);
			unsigned char* const ptr = static_cast<unsigned char*> (vertexPtr->lock(HardwareBuffer::HBL_READ_ONLY));
			for (int i = 0; i < points.GetElementsCount(); i ++) {
				float* data;
				vertexElem->baseVertexPointerToElement(ptr + i * size, &data);
				points[i] = matrix.transformAffine (Vector3 (data[offset + 0], data[offset + 1], data[offset + 2]));
			}
			vertexPtr->unlock();
		}

		dNewtonScopeBuffer<Vector3> normals;
		const VertexElement* const normalElem = v_decl->findElementBySemantic(VES_NORMAL);
		if (normalElem) {
			HardwareVertexBufferSharedPtr normalPtr = v_data->vertexBufferBinding->getBuffer(normalElem->getSource());
			normals.Init (normalPtr->getNumVertices());

			int size = normalPtr->getVertexSize();
			int offset = vertexElem->getOffset() / sizeof (float);
			unsigned char* const ptr = static_cast<unsigned char*> (normalPtr->lock(HardwareBuffer::HBL_READ_ONLY));
			for (int i = 0; i < normals.GetElementsCount(); i ++) {
				float* data;
				vertexElem->baseVertexPointerToElement(ptr + i * size, &data);
				normals[i] = matrix * Vector3 (data[offset + 0], data[offset + 1], data[offset + 2]);
				normals[i] = normals[i].normalise();
			}
			normalPtr->unlock();
		}


		dNewtonScopeBuffer<Vector3> uvs;
		const VertexElement* const uvElem = v_decl->findElementBySemantic(VES_TEXTURE_COORDINATES);
		if (uvElem) {
			HardwareVertexBufferSharedPtr uvPtr = v_data->vertexBufferBinding->getBuffer(uvElem->getSource());
			uvs.Init (uvPtr->getNumVertices());
		
			int size = uvPtr->getVertexSize();
			int offset = vertexElem->getOffset() / sizeof (float);
			unsigned char* const ptr = static_cast<unsigned char*> (uvPtr->lock(HardwareBuffer::HBL_READ_ONLY));
			for (int i = 0; i < uvs.GetElementsCount(); i ++) {
				float* data;
				uvElem->baseVertexPointerToElement(ptr + i * size, &data);
				uvs[i] = Vector3 (data[offset + 0], data[offset + 1], 0.0f);
			}
			uvPtr->unlock();
		}

		//now find more about the index!!
		IndexData* const i_data = sub_mesh->indexData;
		size_t index_count = i_data->indexCount;
		size_t poly_count = index_count / 3;

		// get pointer!
		HardwareIndexBufferSharedPtr i_sptr = i_data->indexBuffer;

		// 16 or 32 bit indices?
		bool uses32bit = (i_sptr->getType()	== HardwareIndexBuffer::IT_32BIT);
		unsigned long* i_Longptr = NULL;
		unsigned short* i_Shortptr = NULL;

		if (uses32bit) {
			i_Longptr = static_cast<unsigned long*> (i_sptr->lock(HardwareBuffer::HBL_READ_ONLY));
		} else {
			i_Shortptr = static_cast<unsigned short*> (i_sptr->lock(HardwareBuffer::HBL_READ_ONLY));
		}

		//now loop through the indices, getting polygon info!
		int i_offset = 0;

		Real poly_verts[3][12];
		memset (poly_verts, 0, sizeof (poly_verts));
		for (size_t i = 0; i < poly_count; i++)	{
			for (int j = 0; j < 3; j++) {
				// index to first vertex!
				int idx = uses32bit ? i_Longptr[i_offset + j] : i_Shortptr[i_offset + j]; 

				poly_verts[j][0] = points[idx].x;
				poly_verts[j][1] = points[idx].y;
				poly_verts[j][2] = points[idx].z;
				poly_verts[j][3] = 0.0f;

				if (normals.GetElementsCount()) {
					poly_verts[j][4] = normals[idx].x;
					poly_verts[j][5] = normals[idx].y;
					poly_verts[j][6] = normals[idx].z;
				}

				if (uvs.GetElementsCount()) {
					poly_verts[j][7] = uvs[idx].x;
					poly_verts[j][8] = uvs[idx].y;
				}
			}
			AddFace(3, &poly_verts[0][0], 12 * sizeof (Real), cs);
			i_offset += 3;
		}
		i_sptr->unlock();
	}
}
Example #8
0
	//-----------------------------------------------------------------------------
	ManualObject::ManualObjectSection* ManualObject::end(void)
	{
		if (!mCurrentSection)
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"You cannot call end() until after you call begin()",
				"ManualObject::end");
		}
		if (mTempVertexPending)
		{
			// bake current vertex
			copyTempVertexToBuffer();
		}

		// pointer that will be returned
		ManualObjectSection* result = NULL;

		RenderOperation* rop = mCurrentSection->getRenderOperation();
		// Check for empty content
		if (rop->vertexData->vertexCount == 0 ||
			(rop->useIndexes && rop->indexData->indexCount == 0))
		{
			// You're wasting my time sonny
			if (mCurrentUpdating)
			{
				// Can't just undo / remove since may be in the middle
				// Just allow counts to be 0, will not be issued to renderer

				// return the finished section (though it has zero vertices)
				result = mCurrentSection;
			}
			else
			{
				// First creation, can really undo
				// Has already been added to section list end, so remove
				mSectionList.pop_back();
				OGRE_DELETE mCurrentSection;

			}
		}
		else // not an empty section
		{

			// Bake the real buffers
			HardwareVertexBufferSharedPtr vbuf;
			// Check buffer sizes
			bool vbufNeedsCreating = true;
			bool ibufNeedsCreating = rop->useIndexes;
            // Work out if we require 16 or 32-bit index buffers
            HardwareIndexBuffer::IndexType indexType = mCurrentSection->get32BitIndices()?  
				HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT;
			if (mCurrentUpdating)
			{
				// May be able to reuse buffers, check sizes
				vbuf = rop->vertexData->vertexBufferBinding->getBuffer(0);
				if (vbuf->getNumVertices() >= rop->vertexData->vertexCount)
					vbufNeedsCreating = false;

				if (rop->useIndexes)
				{
					if ((rop->indexData->indexBuffer->getNumIndexes() >= rop->indexData->indexCount) &&
                        (indexType == rop->indexData->indexBuffer->getType()))
						ibufNeedsCreating = false;
				}

			}
			if (vbufNeedsCreating)
			{
				// Make the vertex buffer larger if estimated vertex count higher
				// to allow for user-configured growth area
				size_t vertexCount = std::max(rop->vertexData->vertexCount, 
					mEstVertexCount);
				vbuf =
					HardwareBufferManager::getSingleton().createVertexBuffer(
						mDeclSize,
						vertexCount,
						mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
							HardwareBuffer::HBU_STATIC_WRITE_ONLY);
				rop->vertexData->vertexBufferBinding->setBinding(0, vbuf);
			}
			if (ibufNeedsCreating)
			{
				// Make the index buffer larger if estimated index count higher
				// to allow for user-configured growth area
				size_t indexCount = std::max(rop->indexData->indexCount, 
					mEstIndexCount);
				rop->indexData->indexBuffer =
					HardwareBufferManager::getSingleton().createIndexBuffer(
						indexType,
						indexCount,
						mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
							HardwareBuffer::HBU_STATIC_WRITE_ONLY);
			}
			// Write vertex data
			vbuf->writeData(
				0, rop->vertexData->vertexCount * vbuf->getVertexSize(), 
				mTempVertexBuffer, true);
			// Write index data
			if(rop->useIndexes)
			{
                if (HardwareIndexBuffer::IT_32BIT == indexType)
                {
                    // direct copy from the mTempIndexBuffer
				    rop->indexData->indexBuffer->writeData(
					    0, 
					    rop->indexData->indexCount 
						    * rop->indexData->indexBuffer->getIndexSize(),
					    mTempIndexBuffer, true);
                }
                else //(HardwareIndexBuffer::IT_16BIT == indexType)
                {
					uint16* pIdx = static_cast<uint16*>(rop->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
					uint32* pSrc = mTempIndexBuffer;
                    for (size_t i = 0; i < rop->indexData->indexCount; i++)
                    {
                        *pIdx++ = static_cast<uint16>(*pSrc++);
                    }
					rop->indexData->indexBuffer->unlock();

                }
			}

			// return the finished section
			result = mCurrentSection;

		} // empty section check

		mCurrentSection = 0;
		resetTempAreas();

		// Tell parent if present
		if (mParentNode)
		{
			mParentNode->needUpdate();
		}

		// will return the finished section or NULL if
		// the section was empty (i.e. zero vertices/indices)
		return result;
	}
	//---------------------------------------------------------------------
	void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits)
	{
		if (!vertexSplits.empty())
		{
			// ok, need to increase the vertex buffer size, and alter some indexes

			// vertex buffers first
			VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding();
			const VertexBufferBinding::VertexBufferBindingMap& bindmap = 
				mVData->vertexBufferBinding->getBindings();
			for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = 
				bindmap.begin(); i != bindmap.end(); ++i)
			{
				HardwareVertexBufferSharedPtr srcbuf = i->second;
				// Derive vertex count from buffer not vertex data, in case using
				// the vertexStart option in vertex data
				size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size();
				// Create new buffer & bind
				HardwareVertexBufferSharedPtr newBuf = 
					HardwareBufferManager::getSingleton().createVertexBuffer(
					srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), 
					srcbuf->hasShadowBuffer());
				newBindings->setBinding(i->first, newBuf);

				// Copy existing contents (again, entire buffer, not just elements referenced)
				newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true);

				// Split vertices, read / write from new buffer
				char* pBase = static_cast<char*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));
				for (VertexSplits::iterator spliti = vertexSplits.begin(); 
					spliti != vertexSplits.end(); ++spliti)
				{
					const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize();
					char* pDstBase = pBase + spliti->second * newBuf->getVertexSize();
					memcpy(pDstBase, pSrcBase, newBuf->getVertexSize());
				}
				newBuf->unlock();

			}

			// Update vertex data
			// Increase vertex count according to num splits
			mVData->vertexCount += vertexSplits.size();
			// Flip bindings over to new buffers (old buffers released)
			HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding);
			mVData->vertexBufferBinding = newBindings;

			// If vertex size requires 32bit index buffer
			if (mVData->vertexCount > 65536)
			{
				for (size_t i = 0; i < mIDataList.size(); ++i)
				{
					// check index size
					IndexData* idata = mIDataList[i];
					HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer;
					if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT)
					{
						size_t indexCount = srcbuf->getNumIndexes();

						// convert index buffer to 32bit.
						HardwareIndexBufferSharedPtr newBuf =
							HardwareBufferManager::getSingleton().createIndexBuffer(
							HardwareIndexBuffer::IT_32BIT, indexCount,
							srcbuf->getUsage(), srcbuf->hasShadowBuffer());

						uint16* pSrcBase = static_cast<uint16*>(srcbuf->lock(HardwareBuffer::HBL_NORMAL));
						uint32* pBase = static_cast<uint32*>(newBuf->lock(HardwareBuffer::HBL_NORMAL));

						size_t j = 0;
						while (j < indexCount)
						{
							*pBase++ = *pSrcBase++;
							++j;
						}

						srcbuf->unlock();
						newBuf->unlock();

						// assign new index buffer.
						idata->indexBuffer = newBuf;
					}
				}
			}
		}

	}
    SkeletonPtr MergeSkeleton::bake()
    {    
        MeshCombiner::getSingleton().log( 
             "Baking: New Skeleton started" );

        SkeletonPtr sp = SkeletonManager::getSingleton().create( "mergeSkeleton", 
             ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true );
        
        for( std::vector< Ogre::SkeletonPtr >::iterator it = m_Skeletons.begin();
             it != m_Skeletons.end(); ++it )
        {   
            if(  it == m_Skeletons.begin() )
            {
                MeshCombiner::getSingleton().log( 
                    "Baking: using " + (*it)->getName() + " as the base skeleton"   );

                MeshCombiner::getSingleton().log( 
                    "Baking: adding bones"   );
                Skeleton::BoneIterator bit = (*it)->getBoneIterator();
                while( bit.hasMoreElements() )
                {
                    Bone* bone = bit.getNext();
                    Bone* newbone = sp->createBone( bone->getName(), bone->getHandle() );
                    newbone->setScale( bone->getScale() );
                    newbone->setOrientation( bone->getOrientation() );
                    newbone->setPosition( bone->getPosition() );
                }
                MeshCombiner::getSingleton().log( 
                    "Baking: building bone hierarchy"   );
                // bone hierarchy
                bit = (*it)->getBoneIterator();
                while( bit.hasMoreElements() )
                {
                    Bone* bone = bit.getNext();
                    Node* pnode = bone->getParent();
                    if( pnode != NULL )
                    {
                        Bone* pbone = static_cast<Bone*>( pnode );
                        sp->getBone( pbone->getHandle() )->addChild( sp->getBone( bone->getHandle() ) );
                    }
                }
            }   

            MeshCombiner::getSingleton().log( 
                "Baking: adding animations for " + (*it)->getName() );

            // insert all animations
            for (unsigned short a=0; a < (*it)->getNumAnimations(); ++a )
            {
                Animation* anim = (*it)->getAnimation( a );
                Animation* newanim = sp->createAnimation( anim->getName(), anim->getLength() );

                if( anim->getNumNodeTracks() > 0 )
                    MeshCombiner::getSingleton().log( 
                        "Baking: adding node tracks" );
                for( unsigned short na=0; na < anim->getNumNodeTracks(); ++na )
                {
                    if( anim->hasNodeTrack( na ) )
                    {
                        NodeAnimationTrack* nat = anim->getNodeTrack( na );
                        NodeAnimationTrack* newnat = newanim->createNodeTrack( na );
                        // all key frames
                        for( unsigned short nf=0; nf < nat->getNumKeyFrames(); ++nf )
                        {
                            TransformKeyFrame* tkf = nat->getNodeKeyFrame( nf );
                            TransformKeyFrame* newtkf = newnat->createNodeKeyFrame( tkf->getTime() );
                            newtkf->setRotation( tkf->getRotation() );
                            newtkf->setTranslate( tkf->getTranslate() );
                            newtkf->setScale( tkf->getScale() );
                        }

                        newnat->setAssociatedNode( sp->getBone( nat->getHandle() ) );
                    }
                }

                if( anim->getNumNumericTracks() > 0 )
                    MeshCombiner::getSingleton().log( 
                        "Baking: adding numeric tracks" );
                for( unsigned short na=0; na < anim->getNumNumericTracks(); ++na )
                {
                    if( anim->hasNumericTrack( na ) )
                    {
                        NumericAnimationTrack* nat = anim->getNumericTrack( na );
                        NumericAnimationTrack* newnat = newanim->createNumericTrack( na );

                        // all key frames
                        for( unsigned short nf=0; nf < nat->getNumKeyFrames(); ++nf )
                        {
                            NumericKeyFrame* nkf = nat->getNumericKeyFrame( nf );
                            NumericKeyFrame* newnkf = newnat->createNumericKeyFrame( nkf->getTime() );
                            newnkf->setValue( nkf->getValue() );
                        }
                    }
                }

                if( anim->getNumVertexTracks() > 0 )
                    MeshCombiner::getSingleton().log( 
                        "Baking: adding vertex tracks" );
                for( unsigned short va=0; va < anim->getNumVertexTracks(); ++va )
                {
                    if( anim->hasVertexTrack( va ) )
                    {
                        VertexAnimationTrack* vat = anim->getVertexTrack( va );
                        VertexAnimationTrack* newvat = newanim->createVertexTrack( va, vat->getAnimationType() );

                        // all key frames
                        for( unsigned short nf=0; nf < vat->getNumKeyFrames(); ++nf )
                        {
                            // all morphs
                            VertexMorphKeyFrame* vmkf = vat->getVertexMorphKeyFrame( nf );
                            if( vmkf != NULL )
                            {
                                VertexMorphKeyFrame* newvmkf = newvat->createVertexMorphKeyFrame( vmkf->getTime() );
                                // @todo vertex buffer copying correct??
                                HardwareVertexBufferSharedPtr buf = vmkf->getVertexBuffer();
                                HardwareVertexBufferSharedPtr newbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
                                    buf->getVertexSize(), buf->getNumVertices(), buf->getUsage(), buf->hasShadowBuffer() );
                                newbuf->copyData( *buf.getPointer(), 0, 0, buf->getSizeInBytes() );
                            }

                            // all poses
                            VertexPoseKeyFrame* vpkf = vat->getVertexPoseKeyFrame( nf );
                            if( vpkf != NULL )
                            {
                                VertexPoseKeyFrame* newvpkf = newvat->createVertexPoseKeyFrame( vpkf->getTime() );
                                
                                VertexPoseKeyFrame::PoseRefIterator pit = vpkf->getPoseReferenceIterator();
                                while( pit.hasMoreElements() )
                                {
                                    VertexPoseKeyFrame::PoseRef pr = pit.getNext();
                                    newvpkf->addPoseReference( pr.poseIndex, pr.influence );
                                }
                            }

                        }
                    }
                }
            }
        }           

        return sp;
	}