//-----------------------------------------------------------------------------
    void TempBlendedBufferInfo::extractFrom(const VertexData* sourceData)
    {
        // Release old buffer copies first
        if (!destPositionBuffer.isNull())
        {
            destPositionBuffer->getManager()->releaseVertexBufferCopy(destPositionBuffer);
            assert(destPositionBuffer.isNull());
        }
        if (!destNormalBuffer.isNull())
        {
            destNormalBuffer->getManager()->releaseVertexBufferCopy(destNormalBuffer);
            assert(destNormalBuffer.isNull());
        }

        VertexDeclaration* decl = sourceData->vertexDeclaration;
        VertexBufferBinding* bind = sourceData->vertexBufferBinding;
        const VertexElement *posElem = decl->findElementBySemantic(VES_POSITION);
        const VertexElement *normElem = decl->findElementBySemantic(VES_NORMAL);

        assert(posElem && "Positions are required");

        posBindIndex = posElem->getSource();
        srcPositionBuffer = bind->getBuffer(posBindIndex);

        if (!normElem)
        {
            posNormalShareBuffer = false;
            srcNormalBuffer.setNull();
        }
        else
        {
            normBindIndex = normElem->getSource();
            if (normBindIndex == posBindIndex)
            {
                posNormalShareBuffer = true;
                srcNormalBuffer.setNull();
            }
            else
            {
                posNormalShareBuffer = false;
                srcNormalBuffer = bind->getBuffer(normBindIndex);
            }
        }
    }
Exemple #2
0
void OgreMesh::syncFromOgreMesh(Ogre::Entity *entity,Ogre::SubMesh*subMesh)
{
  const Ogre::Vector3 &position = entity->getParentNode()->_getDerivedPosition();
  const Ogre::Quaternion &orient = entity->getParentNode()->_getDerivedOrientation();
  const Ogre::Vector3 &scale = entity->getParentNode()->_getDerivedScale();

  VertexData *vertexData = subMesh->vertexData;
  if (vertexData) {
      VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;
      
      // find the element for position
      const VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION);
      
      // find and lock the buffer containing position information
      VertexBufferBinding *bufferBinding = vertexData->vertexBufferBinding;
      HardwareVertexBuffer *buffer = bufferBinding->getBuffer(element->getSource()).get();
      unsigned char *pVert = static_cast<unsigned char*>(buffer->lock(HardwareBuffer::HBL_READ_ONLY));
      std::vector<Ogre::Vector3> lvertices;
      for (size_t vert = 0; vert < vertexData->vertexCount; vert++) {
          Real *vertex = 0;
          Real x, y, z;
          element->baseVertexPointerToElement(pVert, &vertex);
          x = *vertex++;
          y = *vertex++;
          z = *vertex++;
          Ogre::Vector3 vec(x, y, z);
          vec = (orient * (vec * scale)) + position;
          
          lvertices.push_back(vec);
          
          pVert += buffer->getVertexSize();
      }
      buffer->unlock();
      
      // find and lock buffer containg vertex indices
      IndexData * indexData = subMesh->indexData;
      HardwareIndexBuffer *indexBuffer = indexData->indexBuffer.get();
      void *pIndex = static_cast<unsigned char *>(indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
      if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) {
          for (size_t index = indexData->indexStart; index < indexData->indexCount; ) {
              uint16 *uint16Buffer = (uint16 *) pIndex;
              uint16 v1 = uint16Buffer[index++];
              uint16 v2 = uint16Buffer[index++];
              uint16 v3 = uint16Buffer[index++];
              
              mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
          }
      } else if (indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) {
          for (size_t index = indexData->indexStart; index < indexData->indexCount; ) {
              uint32 *uint16Buffer = (uint32 *) pIndex;
              uint32 v1 = uint16Buffer[index++];
              uint32 v2 = uint16Buffer[index++];
              uint32 v3 = uint16Buffer[index++];
              
              mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
          }
      } else {
          assert(0);
      }
      indexBuffer->unlock();
  }
}
	//---------------------------------------------------------------------
	void TangentSpaceCalc::populateVertexArray(unsigned short sourceTexCoordSet)
	{
		// Just pull data out into more friendly structures
		VertexDeclaration *dcl = mVData->vertexDeclaration;
		VertexBufferBinding *bind = mVData->vertexBufferBinding;

		// Get the incoming UV element
		const VertexElement* uvElem = dcl->findElementBySemantic(
			VES_TEXTURE_COORDINATES, sourceTexCoordSet);

		if (!uvElem || uvElem->getType() != VET_FLOAT2)
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"No 2D texture coordinates with selected index, cannot calculate tangents.",
				"TangentSpaceCalc::build");
		}

		HardwareVertexBufferSharedPtr uvBuf, posBuf, normBuf;
		unsigned char *pUvBase, *pPosBase, *pNormBase;
		size_t uvInc, posInc, normInc;

		uvBuf = bind->getBuffer(uvElem->getSource());
		pUvBase = static_cast<unsigned char*>(
			uvBuf->lock(HardwareBuffer::HBL_READ_ONLY));
		uvInc = uvBuf->getVertexSize();
		// offset for vertex start
		pUvBase += mVData->vertexStart * uvInc;

		// find position
		const VertexElement *posElem = dcl->findElementBySemantic(VES_POSITION);
		if (posElem->getSource() == uvElem->getSource())
		{
			pPosBase = pUvBase;
			posInc = uvInc;
		}
		else
		{
			// A different buffer
			posBuf = bind->getBuffer(posElem->getSource());
			pPosBase = static_cast<unsigned char*>(
				posBuf->lock(HardwareBuffer::HBL_READ_ONLY));
			posInc = posBuf->getVertexSize();
			// offset for vertex start
			pPosBase += mVData->vertexStart * posInc;
		}
		// find a normal buffer
		const VertexElement *normElem = dcl->findElementBySemantic(VES_NORMAL);
		if (!normElem)
			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
			"No vertex normals found", 
			"TangentSpaceCalc::build");

		if (normElem->getSource() == uvElem->getSource())
		{
			pNormBase = pUvBase;
			normInc = uvInc;
		}
		else if (normElem->getSource() == posElem->getSource())
		{
			// normals are in the same buffer as position
			// this condition arises when an animated(skeleton) mesh is not built with 
			// an edge list buffer ie no shadows being used.
			pNormBase = pPosBase;
			normInc = posInc;
		}
		else
		{
			// A different buffer
			normBuf = bind->getBuffer(normElem->getSource());
			pNormBase = static_cast<unsigned char*>(
				normBuf->lock(HardwareBuffer::HBL_READ_ONLY));
			normInc = normBuf->getVertexSize();
			// offset for vertex start
			pNormBase += mVData->vertexStart * normInc;
		}

		// Preinitialise vertex info
		mVertexArray.clear();
		mVertexArray.resize(mVData->vertexCount);

		float* pFloat;
		VertexInfo* vInfo = &(mVertexArray[0]);
		for (size_t v = 0; v < mVData->vertexCount; ++v, ++vInfo)
		{
			posElem->baseVertexPointerToElement(pPosBase, &pFloat);
			vInfo->pos.x = *pFloat++;
			vInfo->pos.y = *pFloat++;
			vInfo->pos.z = *pFloat++;
			pPosBase += posInc;

			normElem->baseVertexPointerToElement(pNormBase, &pFloat);
			vInfo->norm.x = *pFloat++;
			vInfo->norm.y = *pFloat++;
			vInfo->norm.z = *pFloat++;
			pNormBase += normInc;

			uvElem->baseVertexPointerToElement(pUvBase, &pFloat);
			vInfo->uv.x = *pFloat++;
			vInfo->uv.y = *pFloat++;
			pUvBase += uvInc;


		}

		// unlock buffers
		uvBuf->unlock();
		if (!posBuf.isNull())
		{
			posBuf->unlock();
		}
		if (!normBuf.isNull())
		{
			normBuf->unlock();
		}

	}
void OgreMesh::syncFromOgreMesh(Ogre::SubMesh*subMesh, bool texcoord, std::vector<TriVertex>& sharedVertices)
{
    VertexData *vertexData;
    std::vector<TriVertex> subVertices;
    std::vector<TriVertex> *lpvertices;

    if (subMesh->useSharedVertices) {
        vertexData = subMesh->parent->sharedVertexData;
        lpvertices=&sharedVertices;
    }else {
        vertexData = subMesh->vertexData;
        lpvertices=&subVertices;
    }
    std::vector<TriVertex>&lvertices=*lpvertices;

    if (vertexData)
    {
        VertexDeclaration *vertexDecl = vertexData->vertexDeclaration;

        // find the element for position
        const VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION);
        const VertexElement *texelement = texcoord ? vertexDecl->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES) : NULL;

        // find and lock the buffer containing position information
        VertexBufferBinding *bufferBinding = vertexData->vertexBufferBinding;
        HardwareVertexBuffer *buffer = bufferBinding->getBuffer(element->getSource()).get();
        if (lvertices.empty()) {
            unsigned char *pVert = static_cast<unsigned char*>(buffer->lock(HardwareBuffer::HBL_READ_ONLY));
            HardwareVertexBuffer *texbuffer = texelement ? bufferBinding->getBuffer(texelement->getSource()).get() : NULL;
            unsigned char *pTexVert = texbuffer
                ? (texbuffer == buffer ? pVert : static_cast<unsigned char*>(texbuffer->lock(HardwareBuffer::HBL_READ_ONLY)))
                : NULL;
            for (size_t vert = 0; vert < vertexData->vertexCount; vert++)
            {
                float *vertex = 0;
                Real x, y, z;
                element->baseVertexPointerToElement(pVert, &vertex);
                x = *vertex++;
                y = *vertex++;
                z = *vertex++;
                Ogre::Vector3 vec(x, y, z);
                Ogre::Vector2 texvec(0,0);
                if (texelement)
                {
                    float *texvertex = 0;
                    float u, v, w;
                    texelement->baseVertexPointerToElement(pTexVert, &texvertex);
                    u = *texvertex++;
                    v = *texvertex++;
                    texvec = Ogre::Vector2(u, v);
                    pTexVert += texbuffer->getVertexSize();
                }

                lvertices.push_back(TriVertex(vec, texvec.x, texvec.y));

                pVert += buffer->getVertexSize();
            }

            buffer->unlock();
        }
        // find and lock buffer containg vertex indices
        Ogre::RenderOperation ro;
        subMesh->_getRenderOperation(ro);
        if (ro.useIndexes)
        {
            IndexData * indexData = subMesh->indexData;
            HardwareIndexBuffer *indexBuffer = indexData->indexBuffer.get();
            void *pIndex = static_cast<unsigned char *>(indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
            if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT)
            {
                for (size_t index = indexData->indexStart; index < indexData->indexCount; )
                {

                    uint16 *uint16Buffer = (uint16 *) pIndex;
                    uint16 v1 = uint16Buffer[index++];
                    uint16 v2 = uint16Buffer[index++];
                    uint16 v3 = uint16Buffer[index++];
                    if (v1 < lvertices.size() && v2 < lvertices.size() && v3 < lvertices.size())
                        mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
                }
            }
            else if (indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT)
            {
                for (size_t index = indexData->indexStart; index < indexData->indexCount; )
                {
                    uint32 *uint16Buffer = (uint32 *) pIndex;
                    uint32 v1 = uint16Buffer[index++];
                    uint32 v2 = uint16Buffer[index++];
                    uint32 v3 = uint16Buffer[index++];
                    if (v1 < lvertices.size() && v2 < lvertices.size() && v3 < lvertices.size())
                        mTriangles.push_back(Triangle(lvertices[v1], lvertices[v2], lvertices[v3]));
                }
            }
            else
            {
                assert(0);
            }
            indexBuffer->unlock();
        }
        else
        {
            for (unsigned int i=0; i<lvertices.size(); i+=3)
            {
                mTriangles.push_back(Triangle(lvertices[i], lvertices[i+1], lvertices[i+2]));
            }
        }
    }
}