//----------------------------------------------------------------------------- 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); } } }
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])); } } } }