void MeshPrivate::setIndexBuffer(const HardwareIndexBuffer& indexbuffer) { HardwareIndexBufferHolder newbuf = indexbuffer.lock(); if ( newbuf != iHardIndexBuffer ) { if ( !iHardIndexBuffer.isInvalid() ) { Resource::removeListener( iHardIndexBuffer->getName() ); } iHardIndexBuffer = newbuf; iHardBuffersChanged = true; if ( !iHardIndexBuffer.isInvalid() ) { Resource::addListener( indexbuffer ); } } }
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 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])); } } } }