void processPositionElement( VertexData* vertexData, const VertexElement* vertexElem ) { int nMaxVert= vertexData->vertexCount ; //const Ogre::VertexElement* VertexEle_POS = vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION ); // get vertex buffer info via the input element Ogre::HardwareVertexBufferSharedPtr VertexBufPOS = vertexData->vertexBufferBinding->getBuffer( vertexElem->getSource() ); //LOCK BUFFER unsigned char* VertexPtrPOS = static_cast<unsigned char*>( VertexBufPOS->lock( Ogre::HardwareBuffer::HBL_NORMAL) ); int VertSizePOS=VertexBufPOS->getVertexSize(); float * pElementPOS=NULL; //A vector of every vertices position std::vector<Ogre::Vector3> positions(nMaxVert); //Copy each position into position vector for(int nVert=0 ; nVert<nMaxVert ; nVert++) { vertexElem->baseVertexPointerToElement( VertexPtrPOS, &pElementPOS ); Ogre::Vector3 vertex(pElementPOS); vertex = mTransform * vertex; pElementPOS[0] = vertex.x; pElementPOS[1] = vertex.y; pElementPOS[2] = vertex.z; mBoundingBox.merge(vertex); VertexPtrPOS+=VertSizePOS ; } //UNLOCK BUFFER if(VertexBufPOS->isLocked()){VertexBufPOS->unlock();} }
//------------------------------------------------------------------------------------------------ void VertexIndexToShape::addStaticVertexData(const Ogre::VertexData *vertex_data) { if (!vertex_data) { return; } const Ogre::VertexData *data = vertex_data; const unsigned int prev_size = mVertexCount; mVertexCount += (unsigned int)data->vertexCount; Ogre::Vector3 *tmp_vert = new Ogre::Vector3[mVertexCount]; if (mVertexBuffer) { memcpy(tmp_vert, mVertexBuffer, sizeof(Ogre::Vector3) * prev_size); delete[] mVertexBuffer; } mVertexBuffer = tmp_vert; // Get the positional buffer element { const Ogre::VertexElement *posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource()); const unsigned int vSize = (unsigned int)vbuf->getVertexSize(); unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float *pReal = NULL; Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size]; const unsigned int vertexCount = (unsigned int)data->vertexCount; for (unsigned int j = 0; j < vertexCount; ++j) { posElem->baseVertexPointerToElement(vertex, &pReal); vertex += vSize; curVertices->x = (*pReal++); curVertices->y = (*pReal++); curVertices->z = (*pReal++); *curVertices = mTransform * (*curVertices); curVertices++; } vbuf->unlock(); } }
//------------------------------------------------------- // http://www.ogre3d.org/tikiwiki/Raycasting+to+the+polygon+level std::pair<bool, float> Ground::GetVertexIntersection(const Ogre::Ray & ray, const Ogre::SubMesh* subMesh) { OgreAssert(false == subMesh->useSharedVertices, "Mesh with shared data is not supported"); const Ogre::VertexElement* posElem = subMesh->vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuffer = subMesh->vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertexes = reinterpret_cast<unsigned char*>(vbuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); size_t count = subMesh->vertexData->vertexCount; float intersection = -1.0f; OgreAssert(count == REGION_SIZE * REGION_SIZE * 4, "Wrong buffer size"); float* pReal; for (size_t i = 0; i < REGION_SIZE * REGION_SIZE; ++i) { Ogre::Vector3 v0, v1, v2, v3; for (auto vp : { &v0, &v1, &v2, &v3 }) { posElem->baseVertexPointerToElement(vertexes, &pReal); *vp = Ogre::Vector3(pReal[0], pReal[1], pReal[2]); vertexes += vbuffer->getVertexSize(); } auto hit1 = Ogre::Math::intersects(ray, v1, v2, v0, true, false); if (hit1.first && (intersection < 0.0f || hit1.second < intersection)) { intersection = hit1.second; } auto hit2 = Ogre::Math::intersects(ray, v3, v2, v1, true, false); if (hit2.first && (intersection < 0.0f || hit2.second < intersection)) { intersection = hit2.second; } } vbuffer->unlock(); if (intersection >= 0.0f) { return std::make_pair(true, intersection); } return std::make_pair(false, -1.0f); }
std::vector<Ogre::Vector3> OgreRecast::getManualObjectVertices(Ogre::ManualObject *manual) { std::vector<Ogre::Vector3> returnVertices; unsigned long thisSectionStart = 0; for (size_t i=0; i < manual->getNumSections(); i++) { Ogre::ManualObject::ManualObjectSection * section = manual->getSection(i); Ogre::RenderOperation * renderOp = section->getRenderOperation(); //Collect the vertices { const Ogre::VertexElement * vertexElement = renderOp->vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vertexBuffer = renderOp->vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource()); char * verticesBuffer = (char*)vertexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); float * positionArrayHolder; thisSectionStart = returnVertices.size(); returnVertices.reserve(returnVertices.size() + renderOp->vertexData->vertexCount); for (unsigned int j=0; j<renderOp->vertexData->vertexCount; j++) { vertexElement->baseVertexPointerToElement(verticesBuffer + j * vertexBuffer->getVertexSize(), &positionArrayHolder); Ogre::Vector3 vertexPos = Ogre::Vector3(positionArrayHolder[0], positionArrayHolder[1], positionArrayHolder[2]); //vertexPos = (orient * (vertexPos * scale)) + position; returnVertices.push_back(vertexPos); } vertexBuffer->unlock(); } } return returnVertices; }
void VertexBuffer::AddFromVertexData(Ogre::VertexData* vertexData) { // Get vertex count const unsigned int addedCount = vertexData->vertexCount; if(_reserved < _size + addedCount) { Reserve(_size + addedCount); } // Get VertexElement with info on used vertex semantics const Ogre::VertexElement* vertexElement = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); // Get actual vertex buffer and its size Ogre::HardwareVertexBufferSharedPtr hardwareBuffer = vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource()); const unsigned int vertexSize = (unsigned int)hardwareBuffer->getVertexSize(); // Lock buffer with read-only to retrieve vertex data unsigned char* buffer = static_cast<unsigned char*>( hardwareBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // Pointer to one component of vertex vector float *curVertexData = NULL; for (unsigned int j = 0; j < addedCount; ++j) { vertexElement->baseVertexPointerToElement(buffer, &curVertexData); buffer += vertexSize; _buffer.push_back(Ogre::Vector3( *curVertexData, *(curVertexData+1) , *(curVertexData+2))); curVertexData += 3; } _size = _buffer.size(); hardwareBuffer->unlock(); }
void GPUBillboardSet::createVertexDataForVertexAndGeometryShaders(const std::vector<PhotoSynth::Vertex>& vertices) { // Setup render operation mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST; mRenderOp.vertexData = OGRE_NEW Ogre::VertexData(); mRenderOp.vertexData->vertexCount = vertices.size(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.useIndexes = false; mRenderOp.indexData = 0; // Vertex format declaration unsigned short sourceBufferIdx = 0; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; size_t currOffset = 0; decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); // Create vertex buffer Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(sourceBufferIdx), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind vertex buffer Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; bind->setBinding(sourceBufferIdx, vbuf); // Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287) Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem(); unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); Ogre::Real* pReal; Ogre::RGBA* pRGBA; Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx); Ogre::VertexDeclaration::VertexElementList::iterator itr; for (unsigned int i=0; i<vertices.size(); ++i ) { const PhotoSynth::Vertex& vertex = vertices[i]; for (itr=elems.begin(); itr!=elems.end(); ++itr) { Ogre::VertexElement& elem = *itr; if (elem.getSemantic() == Ogre::VES_POSITION) { elem.baseVertexPointerToElement(pVert, &pReal); *pReal = vertex.position.x; *pReal++; *pReal = vertex.position.y; *pReal++; *pReal = vertex.position.z; *pReal++; } else if (elem.getSemantic() == Ogre::VES_DIFFUSE) { elem.baseVertexPointerToElement(pVert, &pRGBA); renderSystem->convertColourValue(vertex.color, pRGBA); } } // Go to next vertex pVert += vbuf->getVertexSize(); } vbuf->unlock(); // Set material this->setMaterial("GPUBillboardWithGS"); }
void GPUBillboardSet::createVertexDataForVertexShaderOnly(const std::vector<PhotoSynth::Vertex>& vertices) { // Setup render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.vertexData = OGRE_NEW Ogre::VertexData(); mRenderOp.vertexData->vertexCount = vertices.size() * 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.useIndexes = true; mRenderOp.indexData = OGRE_NEW Ogre::IndexData(); mRenderOp.indexData->indexCount = vertices.size() * 6; mRenderOp.indexData->indexStart = 0; // Vertex format declaration unsigned short sourceBufferIdx = 0; Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; size_t currOffset = 0; decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2); // Create vertex buffer Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(sourceBufferIdx), mRenderOp.vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind vertex buffer Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; bind->setBinding(sourceBufferIdx, vbuf); // Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287) Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem(); unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); Ogre::Real* pReal; Ogre::RGBA* pRGBA; Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx); Ogre::VertexDeclaration::VertexElementList::iterator itr; const Ogre::Vector2 uvs[4] = { Ogre::Vector2( -1.f, 1.f ), Ogre::Vector2( -1.f, -1.f ), Ogre::Vector2( 1.f, -1.f ), Ogre::Vector2( 1.f, 1.f ) }; for (unsigned int i=0; i<vertices.size(); ++i ) { const PhotoSynth::Vertex& vertex = vertices[i]; for ( unsigned int j=0; j<4; j++ ) { for (itr=elems.begin(); itr!=elems.end(); ++itr) { Ogre::VertexElement& elem = *itr; if (elem.getSemantic() == Ogre::VES_POSITION) { elem.baseVertexPointerToElement(pVert, &pReal); *pReal = vertex.position.x; *pReal++; *pReal = vertex.position.y; *pReal++; *pReal = vertex.position.z; *pReal++; } else if (elem.getSemantic() == Ogre::VES_DIFFUSE) { elem.baseVertexPointerToElement(pVert, &pRGBA); renderSystem->convertColourValue(vertex.color, pRGBA); } else if (elem.getSemantic() == Ogre::VES_TEXTURE_COORDINATES && elem.getIndex() == 0) { elem.baseVertexPointerToElement(pVert, &pReal); *pReal = uvs[j].x; *pReal++; *pReal = uvs[j].y; *pReal++; } } // Go to next vertex pVert += vbuf->getVertexSize(); } } vbuf->unlock(); // Create index buffer if (mRenderOp.indexData->indexCount>=65536) { Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_32BIT, mRenderOp.indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); mRenderOp.indexData->indexBuffer = ibuf; Ogre::uint32* indices = static_cast<Ogre::uint32*>(ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD)); Ogre::uint32 indexFirstVertex = 0; const Ogre::uint32 inds[6] = { 0, 1, 2, 3, 0, 2 }; for (unsigned int i=0; i<vertices.size(); ++i) { for (unsigned int j=0; j<6; ++j) { *indices = indexFirstVertex + inds[j]; indices++; } indexFirstVertex +=4; } ibuf->unlock(); } else { Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_16BIT, mRenderOp.indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); mRenderOp.indexData->indexBuffer = ibuf; Ogre::uint16* indices = static_cast<Ogre::uint16*>( ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD ) ); Ogre::uint32 indexFirstVertex = 0; const Ogre::uint16 inds[6] = { 0, 1, 2, 3, 0, 2 }; for ( unsigned int i=0; i<vertices.size(); ++i ) { for ( unsigned int j=0; j<6; ++j ) { *indices = indexFirstVertex + inds[j]; indices++; } indexFirstVertex +=4; } ibuf->unlock(); } // Set material this->setMaterial("GPUBillboard"); }
void Renderer::FindClosestPolygon(Ogre::Entity* entity, float& closestDistance, Ogre::Vector3& position, Ogre::Vector3& normal) { closestDistance = std::numeric_limits<float>::max(); // default value (means // nothing detected) // Get transformation Ogre::SceneNode* parentNode = entity->getParentSceneNode(); Ogre::Vector3 parentPos; Ogre::Quaternion parentOrientation; Ogre::Vector3 parentScale; if (parentNode) { parentPos = parentNode->_getDerivedPosition(); parentOrientation = parentNode->_getDerivedOrientation(); parentScale = parentNode->_getDerivedScale(); } else { parentPos = Ogre::Vector3::ZERO; parentOrientation = Ogre::Quaternion::IDENTITY; parentScale = Ogre::Vector3::UNIT_SCALE; } // Handle animated entities bool isAnimated = entity->hasSkeleton(); if (isAnimated) { entity->addSoftwareAnimationRequest(false); entity->_updateAnimation(); } // Loop through each submesh Ogre::MeshPtr mesh = entity->getMesh(); for (uint i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); // Ignore anything that isn't a triangle List if (subMesh->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST) continue; // Get the vertex data Ogre::VertexData* vertexData; if (subMesh->useSharedVertices) { if (isAnimated) vertexData = entity->_getSkelAnimVertexData(); else vertexData = mesh->sharedVertexData; } else { if (isAnimated) vertexData = entity->getSubEntity(i)->_getSkelAnimVertexData(); else vertexData = subMesh->vertexData; } // Get the size of one vertex const Ogre::VertexElement* posEl = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vBuff = vertexData->vertexBufferBinding->getBuffer(posEl->getSource()); uint vertexSize = vBuff->getVertexSize(); // Save pointer to first vertex short* pVertex = (short*)vBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); short* pStartVertex = pVertex; // Get the index buffer // If it is null then skip as it must be a point cloud Ogre::HardwareIndexBufferSharedPtr iBuff = subMesh->indexData->indexBuffer; if (iBuff.isNull()) continue; uint* pLong = (uint*)iBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); uint16_t* pShort = (uint16_t*)pLong; // Look through each vertex and check each triangle with the ray Ogre::Vector3 vertexPos; Ogre::Vector3 vertex1; Ogre::Vector3 vertex2; float* pReal; uint index; for (uint k = 0; k < subMesh->indexData->indexCount; k++) { // Read index value if (iBuff->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) // if 32bit indexes { index = (uint)pLong[k]; } else { index = (uint)pShort[k]; } // Read referenced vertex pVertex = pStartVertex + (vertexSize * index); // calculate pointer posEl->baseVertexPointerToElement(pVertex, &pReal); // read vertex vertexPos = Ogre::Vector3(pReal[0], pReal[1], pReal[2]); // read position values // Apply world transformations if (parentNode) vertexPos = (parentOrientation * (vertexPos * parentScale)) + parentPos; // Figure out triangle and calculate the distance if it's the closest switch (k % 3) { case 0: vertex1 = vertexPos; break; case 1: vertex2 = vertexPos; break; case 2: RayToTriangleCheck(vertex1, vertex2, vertexPos, closestDistance, position, normal); break; default: break; } } iBuff->unlock(); vBuff->unlock(); } if (isAnimated) { entity->removeSoftwareAnimationRequest(false); } }
void MeshUtils::meshBuffersToArrays(const Ogre::MeshPtr& mesh, Ogre::Vector3* vertices, unsigned long* indices) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; //const Ogre::Vector3 &position = ent->getParentNode()->_getDerivedPosition(); //const Ogre::Quaternion &orient = ent->getParentNode()->_getDerivedOrientation(); //const Ogre::Vector3 &scale = ent->getParentNode()->_getDerivedScale(); const Ogre::Vector3 &position = Ogre::Vector3::ZERO; const Ogre::Quaternion &orient = Ogre::Quaternion::IDENTITY; const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE; Ogre::Mesh::SubMeshIterator itr = mesh->getSubMeshIterator(); while (itr.hasMoreElements()) { Ogre::SubMesh* submesh = itr.getNext(); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared)) { if (submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*> (vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; float* pReal; for (size_t k = 0; k < vertex_data->vertexCount; ++k, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + k] = (orient * (pt * scale)) + position; //vertices[current_offset + k] = pt; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*> (ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*> (pLong); size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset; if (use32bitindexes) { for (size_t k = 0; k < numTris * 3; ++k) { indices[index_offset++] = pLong[k] + static_cast<unsigned long> (offset); } } else { for (size_t k = 0; k < numTris * 3; ++k) { indices[index_offset++] = static_cast<unsigned long> (pShort[k]) + static_cast<unsigned long> (offset); } } ibuf->unlock(); current_offset = next_offset; } }
void BtOgreSoftBody::updateOgreMesh() { Ogre::Node *ogreNode = mEntity->getParentNode(); //printf("updateOgreMesh %d %s %s\n", internalId, mEntity->getName().c_str(), ogreNode->getName().c_str()); Ogre::MeshPtr mesh = mEntity->getMesh(); Ogre::Mesh::SubMeshIterator subMeshI = mesh->getSubMeshIterator(); Ogre::SubMesh* subMesh = NULL; Ogre::VertexData* vData = NULL; Ogre::VertexDeclaration* vDeclaration = NULL; const Ogre::VertexElement* vPosElement = NULL; bool isSharedVerticesAdded = false; unsigned short bufferIndex = 0; Ogre::HardwareVertexBufferSharedPtr vBuffer; // Can not do arithmetic operations on void* unsigned char* lockedMem = NULL; float* vPosition; btSoftBody::tNodeArray& btNodes = mSoftBody->m_nodes; //printf("Bullet nodes size %d\n", btNodes.size()); int ogreVertexIdx = 0; while (subMeshI.hasMoreElements()) { subMesh = subMeshI.getNext(); if (subMesh->useSharedVertices) { if (isSharedVerticesAdded) { continue; } vData = mesh->sharedVertexData; // We need to add shared vertices only once isSharedVerticesAdded = true; } else { vData = subMesh->vertexData; } vDeclaration = vData->vertexDeclaration; vPosElement = vDeclaration->findElementBySemantic(Ogre::VES_POSITION); bufferIndex = vPosElement->getSource(); vBuffer = vData->vertexBufferBinding->getBuffer(bufferIndex); // Lock the buffer before reading from it lockedMem = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); // Read each vertex for (unsigned int i = 0; i < vData->vertexCount; ++i) { vPosElement->baseVertexPointerToElement(lockedMem, &vPosition); int idx = getBulletIndex(ogreVertexIdx); *vPosition++ = btNodes[idx].m_x.x(); *vPosition++ = btNodes[idx].m_x.y(); *vPosition = btNodes[idx++].m_x.z(); // Point to the next vertex lockedMem += vBuffer->getVertexSize(); ogreVertexIdx++; } vBuffer->unlock(); } btTransform transform = mSoftBody->getWorldTransform(); btQuaternion rot = transform.getRotation(); ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z()); btVector3 pos = transform.getOrigin(); ogreNode->setPosition(pos.x(), pos.y(), pos.z()); }
//----------------------------------------------------------------------- void MeshInfo::getMeshInformation( Ogre::MeshPtr mesh, const Vector3 &position, const Quaternion &orient, const Vector3 &scale) { size_t vertexCount = 0; size_t indexCount = 0; Vector3* vertices = 0; Vector3* normals; unsigned long* indices = 0; bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; // Calculate how many vertices and indices we're going to need for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertexCount += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertexCount += submesh->vertexData->vertexCount; } // Add the indices indexCount += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertexCount]; normals = new Vector3[vertexCount]; indices = new unsigned long[indexCount]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); const Ogre::VertexElement* normalElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; normalElem->baseVertexPointerToElement(vertex, &pReal); Vector3 nt(pReal[0], pReal[1], pReal[2]); normals[current_offset + j] = nt; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; size_t numTrisMultThree = numTris*3; if ( use32bitindexes ) { for ( size_t k = 0; k < numTrisMultThree; ++k) { indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for ( size_t k = 0; k < numTrisMultThree; ++k) { indices[index_offset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); current_offset = next_offset; } // Create triangles from the retrieved data for (size_t k = 0; k < indexCount-1; k+=3) { Triangle t; t.v1 = vertices [indices[k]]; t.vn1 = normals [indices[k]]; t.v2 = vertices [indices[k+1]]; t.vn2 = normals [indices[k+1]]; t.v3 = vertices [indices[k+2]]; t.vn3 = normals [indices[k+2]]; t.calculateSquareSurface(); t.calculateSurfaceNormal(); t.calculateEdgeNormals(); _triangles.push_back(t); } // Delete intermediate arrays delete [] indices; delete [] normals; delete [] vertices; // Sort the triangle on their size, if needed (only if a gaussian random number generator // function is used to perform a random lookup of a triangle) if (mDistribution == MSD_HOMOGENEOUS) sort(_triangles.begin(), _triangles.end(), SortDescending()); else if (mDistribution == MSD_HETEROGENEOUS_1) sort(_triangles.begin(), _triangles.end(), SortAscending()); }
void Utils::GetMeshInformation( const Ogre::MeshPtr mesh, size_t &vertexCount, Ogre::Vector3* &vertices, size_t &indexCount, unsigned* &indices) { bool addShared = false; size_t currentOffset = 0; size_t shared_offset = 0; size_t nextOffset = 0; size_t indexOffset = 0; vertexCount = indexCount = 0; for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); if(submesh->useSharedVertices) { if( !addShared ) { vertexCount += mesh->sharedVertexData->vertexCount; addShared = true; } } else { vertexCount += submesh->vertexData->vertexCount; } indexCount += submesh->indexData->indexCount; } vertices = new Ogre::Vector3[vertexCount]; indices = new unsigned[indexCount]; addShared = false; for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !addShared)) { if(submesh->useSharedVertices) { addShared = true; shared_offset = currentOffset; } const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal; for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[currentOffset + j] = pt; } vbuf->unlock(); nextOffset += vertexData->vertexCount; } Ogre::IndexData* indexData = submesh->indexData; size_t numTris = indexData->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : currentOffset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); currentOffset = nextOffset; } }
bool MaterialVertexBuffer::setSubMeshColors( EntityMaterial* entity, unsigned short mesh_index, size_t ui32VertexColorCount, const float* pVertexColorArray) const { if(entity->getOgreEntity() == NULL) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no Entity found!\n"; return false; } Ogre::Mesh* mesh = entity->getOgreEntity()->getMesh().get(); if(mesh == NULL || mesh_index >= mesh->getNumSubMeshes()) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no Mesh found!\n"; return false; } Ogre::SubMesh* submesh = mesh->getSubMesh( mesh_index ); if(submesh->useSharedVertices) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : vertices are shared and thus not accessible from SubMesh!\n"; return false; } else { if(ui32VertexColorCount != submesh->vertexData->vertexCount) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : vertex count mismatch!\n"; return false; } //get pointer to submesh vertex data Ogre::VertexData* vertex_data = submesh->vertexData; //get pointer to DIFFUSE element const Ogre::VertexElement* difElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_DIFFUSE); if(difElem == NULL) { m_rKernelContext.getLogManager() << LogLevel_Error << "Can't set colors : no colours_diffuse element found in vertex buffer!\n"; return false; } //convert color to current RenderSystem's format Ogre::VertexElementType type = difElem->getType(); //retrieve VB for DIFFUSE element Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(difElem->getSource()); //lock VB for reading unsigned char* color = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; Ogre::RGBA* pRGBA; Ogre::ColourValue colour; for( size_t j = 0; j < vertex_data->vertexCount; ++j, color += vbuf->getVertexSize()) { //get pointer to RGBA DIFFUSE data difElem->baseVertexPointerToElement(color, &pRGBA); colour.r = pVertexColorArray[4*j]; colour.g = pVertexColorArray[4*j+1]; colour.b = pVertexColorArray[4*j+2]; colour.a = pVertexColorArray[4*j+3]; //convert color from RGBA floats to a single ARGB uint32 if(type == Ogre::VET_COLOUR_ARGB) //D3D format { *pRGBA = colour.getAsARGB(); } else /*if type == OGRE::VET_COLOUR_ABGR)*/ //GL format { *pRGBA = colour.getAsABGR(); } } //unlock VB vbuf->unlock(); } return true; }
void PhysicsManager::getMeshInformation(Ogre::MeshPtr mesh,size_t &vertex_count,Vector3* &vertices, size_t &index_count, unsigned* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient,const Ogre::Vector3 &scale) { vertex_count = index_count = 0; bool added_shared = false; size_t current_offset = vertex_count; size_t shared_offset = vertex_count; size_t next_offset = vertex_count; size_t index_offset = index_count; size_t prev_vert = vertex_count; size_t prev_ind = index_count; // Calculate how many vertices and indices we're going to need for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if(!added_shared) { VertexData* vertex_data = mesh->sharedVertexData; vertex_count += vertex_data->vertexCount; added_shared = true; } } else { VertexData* vertex_data = submesh->vertexData; vertex_count += vertex_data->vertexCount; } // Add the indices Ogre::IndexData* index_data = submesh->indexData; index_count += index_data->indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertex_count]; indices = new unsigned[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* pReal; for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Vector3 pt; pt.x = (*pReal++); pt.y = (*pReal++); pt.z = (*pReal++); pt = (orient * (pt * scale)) + position; vertices[current_offset + j].x = pt.x; vertices[current_offset + j].y = pt.y; vertices[current_offset + j].z = pt.z; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; unsigned short* pShort; unsigned int* pInt; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); for(size_t k = 0; k < numTris; ++k) { size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset; unsigned int vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 0] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 1] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 2] = vindex + offset; index_offset += 3; } ibuf->unlock(); current_offset = next_offset; } }
/* ----------------------------------------------------------------------- | the function describe retrieve vertexbuffer from Ogre entity : | (Ref:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=RetrieveVertexData) | | @prama in : Ogre entity | @pamra out : vertex buffer, size of vertexbuffer, vertex indices, sizeof vertex indices ----------------------------------------------------------------------- */ void getVertexBuffer(Ogre::Entity* ent, void* &vertices, size_t& vertexCount, void* &indices, size_t& indexCount) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertexCount = indexCount = 0; const Ogre::MeshPtr& mesh = ent->getMesh(); // Calculate vertexCount, indexCount for ( Ogre::ushort i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); if (subMesh->useSharedVertices) { if( !added_shared ) { vertexCount += mesh->sharedVertexData->vertexCount; added_shared = true; } vertexCount += mesh->sharedVertexData->vertexCount; } else vertexCount += subMesh->vertexData->vertexCount; indexCount += subMesh->indexData->indexCount; } // Alloc vertices, indices vertices = new Ogre::Vector3[ vertexCount ]; indices = new Ogre::ulong[ indexCount ]; added_shared = false; // Assign vertices data, indices data for (Ogre::ushort i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = subMesh->useSharedVertices ? mesh->sharedVertexData : subMesh->vertexData; if ((!subMesh->useSharedVertices) || (subMesh->useSharedVertices && !added_shared)) { if(subMesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } // Retrieve vertices const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); Ogre::uchar* vertex = static_cast<Ogre::uchar*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* data; for (size_t j = 0 ; j < vertexData->vertexCount ; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &data); Ogre::Vector3 origin(data[0], data[1], data[2]); // ((Ogre::Vector3*)vertices)[ current_offset + j ] = (orient * (origin * scale)) + position; ((Ogre::Vector3*)vertices)[ current_offset + j ] = origin; } // End for vbuf->unlock(); next_offset += vertexData->vertexCount; } // End if // Retrieve indices Ogre::IndexData* indexData = subMesh->indexData; size_t trisCount = indexData->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); void* index = (ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::ulong offset = (subMesh->useSharedVertices) ? shared_offset : current_offset; for (Ogre::ulong k = 0; k < trisCount * 3; ++k) { if ( use32bitindexes ) ((Ogre::ulong*)indices)[ index_offset++ ] = ((Ogre::ulong*)index)[ k + offset ]; else ((Ogre::ulong*)indices)[ index_offset++ ] = ((Ogre::ushort*)index)[ k + offset ]; } ibuf->unlock(); current_offset = next_offset; } // End for }
Mesh loadMesh(const std::string& meshName) { Mesh result; bool addedShared = false; size_t currentOffset = 0; size_t sharedOffset = 0; size_t nextOffset = 0; size_t indexOffset = 0; const v3 scale = v3::UNIT_SCALE; const v3 position = v3::ZERO; const qv4 orientation = qv4::IDENTITY; Ogre::MeshManager* mm = Ogre::MeshManager::getSingletonPtr(); if (! mm) { initOgreForMeshLoading(); mm = Ogre::MeshManager::getSingletonPtr(); } Ogre::MeshPtr mesh = mm->load(meshName, "General"); // Calculate how many result.mVertices and result.mIndices we're going to need for (unsigned short i=0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); // We only need to add the shared result.mVertices once if (subMesh->useSharedVertices) { if (!addedShared) { result.mVertexCount += mesh->sharedVertexData->vertexCount; addedShared = true; } } else { result.mVertexCount += subMesh->vertexData->vertexCount; } result.mIndexCount += subMesh->indexData->indexCount; } result.mVertices.reset(new v3[result.mVertexCount]); result.mIndices.reset(new u32[result.mIndexCount]); addedShared = false; // Run through the sub-meshes again, adding the data into the arrays for (unsigned short i=0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = subMesh->useSharedVertices ? mesh->sharedVertexData : subMesh->vertexData; if((!subMesh->useSharedVertices) || (subMesh->useSharedVertices && !addedShared)) { if(subMesh->useSharedVertices) { addedShared = true; sharedOffset = currentOffset; } const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be compiled/typedefed as double: float* pReal; for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); v3 pt(pReal[0], pReal[1], pReal[2]); result.mVertices[currentOffset + j] = (orientation * (pt * scale)) + position; } vbuf->unlock(); nextOffset += vertexData->vertexCount; } Ogre::IndexData* index_data = subMesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (subMesh->useSharedVertices)? sharedOffset : currentOffset; if (use32bitindexes) { for (size_t k = 0; k < numTris*3; ++k) { result.mIndices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for (size_t k = 0; k < numTris*3; ++k) { result.mIndices[indexOffset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); currentOffset = nextOffset; } return result; }
void GetTrianglesFromMesh(Ogre::Mesh* mesh, std::vector<float3>& dest) { dest.clear(); try { for(uint i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertices = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); size_t vertexSize = vbuf->getVertexSize(); float* pReal = 0; Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; u32* pLong = static_cast<u32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); u16* pShort = reinterpret_cast<u16*>(pLong); bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); if (use32bitindexes) { for(size_t k = 0; k < numTris * 3; k += 3) { uint i1 = pLong[k]; uint i2 = pLong[k+1]; uint i3 = pLong[k+2]; posElem->baseVertexPointerToElement(vertices + i1 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i2 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i3 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); } } else { for(size_t k = 0; k < numTris * 3; k += 3) { uint i1 = pShort[k]; uint i2 = pShort[k+1]; uint i3 = pShort[k+2]; posElem->baseVertexPointerToElement(vertices + i1 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i2 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); posElem->baseVertexPointerToElement(vertices + i3 * vertexSize, &pReal); dest.push_back(float3(pReal[0], pReal[1], pReal[2])); } } vbuf->unlock(); ibuf->unlock(); } } catch(Ogre::Exception &e) { ///\todo Fix Ogre to not allow meshes like this to be successfully created. LogError("GetTrianglesFromMesh failed for mesh! Ogre threw an exception: " + QString(e.what())); dest.clear(); } }
PhysicsObject* PhysicsMgr::createConvexHull(String meshname,Ogre::Vector3 pos,Ogre::Vector3 scale) { bool newshape = false; size_t vertex_count; float* vertices; size_t index_count; vertex_count = index_count = 0; bool added_shared = false; size_t current_offset = vertex_count; size_t shared_offset = vertex_count; size_t next_offset = vertex_count; size_t index_offset = index_count; size_t prev_vert = vertex_count; size_t prev_ind = index_count; std::vector<Ogre::Vector3> vertVect; btConvexShape *convexShape; //btShapeHull* hull; if(meshname=="CUBE"||meshname=="BOX") { return createCube(scale,pos); } if(mShapes.find(meshname)==mShapes.end()) { newshape = true; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingletonPtr()->load(meshname,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // Calculate how many vertices and indices we're going to need for(int i = 0;i < mesh->getNumSubMeshes();i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if(!added_shared) { Ogre::VertexData* vertex_data = mesh->sharedVertexData; vertex_count += vertex_data->vertexCount; added_shared = true; } } else { Ogre::VertexData* vertex_data = submesh->vertexData; vertex_count += vertex_data->vertexCount; } // Add the indices Ogre::IndexData* index_data = submesh->indexData; index_count += index_data->indexCount; } // Allocate space for the vertices and indices int a = vertex_count; vertices = new float[vertex_count*3]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for(int i = 0;i < mesh->getNumSubMeshes();i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* pReal; for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt; pt.x = (*pReal++); pt.y = (*pReal++); pt.z = (*pReal++); bool skip = false; // ignore duped verts for(unsigned int i=0;i<vertVect.size();++i) { if(vertVect[i]==pt) { skip = true; //std::cout<<"IGNORED!\n"; } } // skipping duped verts caused some kind of f-up, TOBEFIXED eventually if(!skip) { vertices[current_offset + (j*3)] = pt.x*0.92f; vertices[current_offset + (j*3) + 1] = pt.y*0.92f; vertices[current_offset + (j*3) + 2] = pt.z*0.92f; vertVect.push_back(pt); } } vbuf->unlock(); next_offset += vertex_data->vertexCount; } } convexShape = new btConvexHullShape(static_cast<btScalar*>(vertices),vertVect.size(),3*sizeof(btScalar)); //create a hull approximation btConvexShape *finalShape = 0; //std::cout<<"size: "<<vertVect.size()<<"\n"; // seemed kinda iffy? //if(vertVect.size()>75) //{ // hull = new btShapeHull(convexShape); // btScalar margin = convexShape->getMargin(); // hull->buildHull(margin); // //btConvexHullShape* simplifiedConvexShape = new btConvexHullShape(hull->getVertexPointer(),hull->numVertices()); // // btConvexHullShape* simplifiedConvexShape = new btConvexHullShape(); // for (int i=0;i<hull->numVertices();i++) // { // btVector3 vect = hull->getVertexPointer()[i]*0.9; // std::cout<<"Vert: "<<vect.x()<<" "<<vect.y()<<" "<<vect.z()<<"\n"; // simplifiedConvexShape->addPoint(vect); // } // mShapes[meshname] = (simplifiedConvexShape); // finalShape = simplifiedConvexShape; //} //else //{ mShapes[meshname] = (convexShape); finalShape = convexShape; //} } //finalShape->setMargin(0.f); btVector3 localInertia(0,0,0); mShapes[meshname]->calculateLocalInertia(180.f,localInertia); btRigidBody* actor = new btRigidBody(180.f,0,mShapes[meshname],localInertia); actor->setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(pos.x,pos.y,pos.z))); actor->setRestitution(0.f); actor->setFriction(0.8f); //actor->setAnisotropicFriction(btVector3(0.3f,0.3f,0.3f)); actor->setDamping(0.2f,0.7f); dynamic_cast<btDiscreteDynamicsWorld*>(mDynamicsWorld)->addRigidBody(actor,COLLISION_GROUP_1,COLLISION_GROUP_1); mObjects.push_back(new PhysicsObject(actor,mDynamicsWorld)); if(newshape) { delete[] vertices; //if(vertVect.size()>75) //{ // delete hull; // delete convexShape; //} } return mObjects[mObjects.size()-1]; }
// Get the mesh information for the given mesh. // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh, size_t &vertex_count, Ogre::Vector3* &vertices, size_t &index_count, Ogre::uint32* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient, const Ogre::Vector3 &scale) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertex_count = index_count = 0; // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Ogre::Vector3[vertex_count]; indices = new Ogre::uint32[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will // be comiled/typedefed as double: // Ogre::Ogre::Real* pOgre::Real; float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); Ogre::uint32* pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) + static_cast<Ogre::uint32>(offset); } } ibuf->unlock(); current_offset = next_offset; } }
//------------------------------------------------------------------------------------------------ void VertexIndexToShape::addAnimatedVertexData(const Ogre::VertexData *vertex_data, const Ogre::VertexData *blend_data, const Ogre::Mesh::IndexMap *indexMap) { // Get the bone index element assert(vertex_data); const Ogre::VertexData *data = blend_data; const unsigned int prev_size = mVertexCount; mVertexCount += (unsigned int)data->vertexCount; Ogre::Vector3 *tmp_vert = new Ogre::Vector3[mVertexCount]; if (mVertexBuffer) { memcpy(tmp_vert, mVertexBuffer, sizeof(Ogre::Vector3) * prev_size); delete[] mVertexBuffer; } mVertexBuffer = tmp_vert; // Get the positional buffer element { const Ogre::VertexElement *posElem = data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); assert(posElem); Ogre::HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(posElem->getSource()); const unsigned int vSize = (unsigned int)vbuf->getVertexSize(); unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float *pReal; Ogre::Vector3 * curVertices = &mVertexBuffer[prev_size]; const unsigned int vertexCount = (unsigned int)data->vertexCount; for (unsigned int j = 0; j < vertexCount; ++j) { posElem->baseVertexPointerToElement(vertex, &pReal); vertex += vSize; curVertices->x = (*pReal++); curVertices->y = (*pReal++); curVertices->z = (*pReal++); *curVertices = mTransform * (*curVertices); curVertices++; } vbuf->unlock(); } { const Ogre::VertexElement *bneElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_BLEND_INDICES); assert(bneElem); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(bneElem->getSource()); const unsigned int vSize = (unsigned int)vbuf->getVertexSize(); unsigned char *vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned char *pBone = NULL; if (!mBoneIndex) { mBoneIndex = new BoneIndex(); } Ogre::Vector3 *curVertices = &mVertexBuffer[prev_size]; const unsigned int vertexCount = (unsigned int)vertex_data->vertexCount; for (unsigned int j = 0; j < vertexCount; ++j) { bneElem->baseVertexPointerToElement(vertex, &pBone); vertex += vSize; const unsigned char currBone = (indexMap) ? (*indexMap)[*pBone] : *pBone; const BoneIndex::iterator i = mBoneIndex->find(currBone); Vector3Array *l = NULL; if (i == mBoneIndex->end()) { l = new Vector3Array; mBoneIndex->insert(BoneKeyIndex(currBone, l)); } else { l = i->second; } l->push_back(*curVertices); curVertices++; } vbuf->unlock(); } }
void RigidObject::extractMeshPositions(const Ogre::Mesh *const mesh) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; n_positions_ = 0; // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh *submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if (submesh->useSharedVertices) { if (!added_shared) { n_positions_ += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { n_positions_ += submesh->vertexData->vertexCount; } } // Allocate space for the vertices positions_.resize(3 * n_positions_); added_shared = false; // Run through the submeshes again, adding the data into the vector for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh *submesh = mesh->getSubMesh(i); Ogre::VertexData *vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared)) { if (submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement *posElem = vertex_data->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char *vertex = static_cast<unsigned char *>( vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or // a double // as second argument. So make it float, to avoid trouble when Ogre::Real // will // be compiled/typedefed as double: // Ogre::Real* pReal; float *pReal; for (size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); // vertices[current_offset + j] = (orient * (pt * scale)) + // position; size_t IND = 3 * (current_offset + j); positions_.at(IND) = pt.x; positions_.at(IND + 1) = pt.y; // positions_.at(IND+2) = -pt.z; // flip z positions_.at(IND + 2) = pt.z; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } } }
void OgreMeshAsset::CreateKdTree() { meshData.Clear(); normals.clear(); uvs.clear(); subMeshTriangleCounts.clear(); for(unsigned short i = 0; i < ogreMesh->getNumSubMeshes(); ++i) { Ogre::SubMesh *submesh = ogreMesh->getSubMesh(i); assert(submesh); Ogre::VertexData *vertexData = submesh->useSharedVertices ? ogreMesh->sharedVertexData : submesh->vertexData; assert(vertexData); const Ogre::VertexElement *posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); if (!posElem) { subMeshTriangleCounts.push_back(0); continue; // No position element. Ignore this submesh. } Ogre::HardwareVertexBufferSharedPtr vbufPos = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char *pos = (unsigned char*)vbufPos->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); assert(pos); size_t posOffset = posElem->getOffset(); size_t posSize = vbufPos->getVertexSize(); // Texcoord element is not mandatory unsigned char *texCoord = 0; size_t texOffset = 0; size_t texSize = 0; Ogre::HardwareVertexBufferSharedPtr vbufTex; const Ogre::VertexElement *texElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES); if (texElem) { vbufTex = vertexData->vertexBufferBinding->getBuffer(texElem->getSource()); // Check if the texcoord buffer is different than the position buffer, in that case lock it separately if (vbufTex != vbufPos) texCoord = static_cast<unsigned char*>(vbufTex->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else texCoord = pos; texOffset = texElem->getOffset(); texSize = vbufTex->getVertexSize(); } Ogre::IndexData *indexData = submesh->indexData; Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; u32 *pLong = (u32*)ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); u16 *pShort = (u16*)pLong; const bool use32BitIndices = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); for(unsigned j = 0; j+2 < indexData->indexCount; j += 3) { unsigned i0, i1, i2; if (use32BitIndices) { i0 = pLong[j]; i1 = pLong[j+1]; i2 = pLong[j+2]; } else { i0 = pShort[j]; i1 = pShort[j+1]; i2 = pShort[j+2]; } float3 v0 = *(float3*)(pos + posOffset + i0 * posSize); float3 v1 = *(float3*)(pos + posOffset + i1 * posSize); float3 v2 = *(float3*)(pos + posOffset + i2 * posSize); Triangle t(v0, v1, v2); meshData.AddObjects(&t, 1); if (texElem) { uvs.push_back(*((float2*)(texCoord + texOffset + i0 * texSize))); uvs.push_back(*((float2*)(texCoord + texOffset + i1 * texSize))); uvs.push_back(*((float2*)(texCoord + texOffset + i2 * texSize))); } float3 edge1 = v1 - v0; float3 edge2 = v2 - v0; float3 normal = edge1.Cross(edge2); normal.Normalize(); normals.push_back(normal); } subMeshTriangleCounts.push_back((int)(indexData->indexCount / 3)); vbufPos->unlock(); if (!vbufTex.isNull() && vbufTex != vbufPos) vbufTex->unlock(); ibuf->unlock(); } { PROFILE(OgreMeshAsset_KdTree_Build); meshData.Build(); } }
CompoundCollisionShape* CollisionShapeManager::PerformConvexDecomposition(const String& Name, Graphics::Mesh* ObjectMesh, Whole Depth, Real CPercent, Real PPercent, Boole UseAllSubmeshes) { //new submesh friendly code Ogre::MeshPtr myMesh = ObjectMesh->_GetInternalMesh(); Ogre::SubMesh* subMesh = NULL; Ogre::IndexData* indexData = NULL; Ogre::VertexData* vertexData = NULL; Boole use32bitindexes = false; unsigned int currtriCount = 0; unsigned int triCount = 0; unsigned int vCount = 0; unsigned int iCount = 0; Whole VertPrevSize = 0; Whole IndiPrevSize = 0; Boole SharedVerts = myMesh->getSubMesh(0)->useSharedVertices; Whole* VertPerSubMesh = NULL; if(UseAllSubmeshes) { VertPerSubMesh = new Whole[myMesh->getNumSubMeshes()]; for( Whole X = 0 ; X < myMesh->getNumSubMeshes() ; X++ ) { vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount; iCount += myMesh->getSubMesh(X)->indexData->indexCount; VertPerSubMesh[X] = SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount; } }else{ vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(0)->vertexData->vertexCount; iCount += myMesh->getSubMesh(0)->indexData->indexCount; } Ogre::Vector3* vertices = new Ogre::Vector3[vCount]; unsigned int* indices = new unsigned int[iCount]; for( unsigned short int SubMeshIndex = 0 ; SubMeshIndex < myMesh->getNumSubMeshes() ; SubMeshIndex++ ) { if( !UseAllSubmeshes && (SubMeshIndex > 0) ) break; if( SharedVerts && (SubMeshIndex > 0) ) break; subMesh = myMesh->getSubMesh(SubMeshIndex); indexData = subMesh->indexData; vertexData = SharedVerts ? myMesh->sharedVertexData : myMesh->getSubMesh(SubMeshIndex)->vertexData; const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vBuffer = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); Ogre::HardwareIndexBufferSharedPtr iBuffer = indexData->indexBuffer; currtriCount=indexData->indexCount/3; triCount+=(indexData->indexCount/3); unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal = NULL; for( size_t j = 0 ; j < vertexData->vertexCount ; j++, vertex += vBuffer->getVertexSize() ) { posElem->baseVertexPointerToElement(vertex, &pReal); vertices[j + VertPrevSize].x = *pReal++; vertices[j + VertPrevSize].y = *pReal++; vertices[j + VertPrevSize].z = *pReal++; } vBuffer->unlock(); size_t index_offset = 0; use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); if( use32bitindexes ) { for (size_t k = 0; k < currtriCount*3; ++k) { if(SubMeshIndex > 0 && VertPerSubMesh) { indices[index_offset+IndiPrevSize] = pLong[k] + VertPerSubMesh[SubMeshIndex]; }else{ indices[index_offset+IndiPrevSize] = pLong[k]; } index_offset++; } }else{ for( size_t k = 0 ; k < currtriCount * 3 ; ++k ) { if(SubMeshIndex > 0 && VertPerSubMesh) { indices[index_offset+IndiPrevSize] = (static_cast<unsigned long>(pShort[k])) + VertPerSubMesh[SubMeshIndex]; }else{ indices[index_offset+IndiPrevSize] = static_cast<unsigned long>(pShort[k]); } index_offset++; } } iBuffer->unlock(); VertPrevSize += vertexData->vertexCount; IndiPrevSize += indexData->indexCount; } ConvexDecomposition::DecompDesc desc; desc.mVcount = vertexData->vertexCount; desc.mTcount = triCount; desc.mVertices = &vertices[0].x; desc.mIndices = &indices[0]; unsigned int maxv = 16; float skinWidth = 0.0; desc.mDepth = Depth; desc.mCpercent = CPercent; desc.mPpercent = PPercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; Internal::MezzConvexDecomposition decomp; desc.mCallback = &decomp; ConvexBuilder cb(desc.mCallback); cb.process(desc); CompoundCollisionShape* compound = new CompoundCollisionShape(Name); btTransform trans; trans.setIdentity(); for (int i=0;i<decomp.m_convexShapes.size();i++) { std::stringstream namestream; namestream << Name << "Child" << i; Vector3 centroid(decomp.m_convexCentroids[i]); ConvexHullCollisionShape* convexShape = new ConvexHullCollisionShape(namestream.str(),decomp.m_convexShapes[i]); compound->AddChildShape(convexShape,centroid); } delete[] vertices; delete[] indices; delete[] VertPerSubMesh; return compound; }
void OgreMeshRay::GetMeshInformation(const Ogre::ManualObject* manual, size_t& vertex_count, Ogre::Vector3*& vertices, size_t& index_count, unsigned long*& indices, const Ogre::Vector3& position, const Ogre::Quaternion& orient, const Ogre::Vector3& scale) { std::vector<Ogre::Vector3> returnVertices; std::vector<unsigned long> returnIndices; unsigned long thisSectionStart = 0; for (unsigned int i = 0, size = manual->getNumSections(); i < size; ++i) { Ogre::ManualObject::ManualObjectSection* section = manual->getSection( i); Ogre::RenderOperation* renderOp = section->getRenderOperation(); std::vector<Ogre::Vector3> pushVertices; //Collect the vertices { const Ogre::VertexElement* vertexElement = renderOp->vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vertexBuffer = renderOp->vertexData->vertexBufferBinding->getBuffer( vertexElement->getSource()); char* verticesBuffer = static_cast<char*>(vertexBuffer->lock( Ogre::HardwareBuffer::HBL_READ_ONLY)); float* positionArrayHolder; thisSectionStart = returnVertices.size() + pushVertices.size(); pushVertices.reserve(renderOp->vertexData->vertexCount); for (unsigned int j = 0; j < renderOp->vertexData->vertexCount; ++j) { vertexElement->baseVertexPointerToElement( verticesBuffer + j * vertexBuffer->getVertexSize(), &positionArrayHolder); Ogre::Vector3 vertexPos = Ogre::Vector3(positionArrayHolder[0], positionArrayHolder[1], positionArrayHolder[2]); vertexPos = (orient * (vertexPos * scale)) + position; pushVertices.push_back(vertexPos); } vertexBuffer->unlock(); } //Collect the indices { if (renderOp->useIndexes) { Ogre::HardwareIndexBufferSharedPtr indexBuffer = renderOp->indexData->indexBuffer; if (indexBuffer.isNull() || renderOp->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST) { //No triangles here, so we just drop the collected vertices and move along to the next section. continue; } else { returnVertices.reserve( returnVertices.size() + pushVertices.size()); returnVertices.insert(returnVertices.end(), pushVertices.begin(), pushVertices.end()); } unsigned int* pLong = static_cast<unsigned int*>(indexBuffer->lock( Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); returnIndices.reserve( returnIndices.size() + renderOp->indexData->indexCount); for (size_t j = 0; j < renderOp->indexData->indexCount; ++j) { unsigned long index; //We also have got to remember that for a multi section object, each section has //different vertices, so the indices will not be correct. To correct this, we //have to add the position of the first vertex in this section to the index //(At least I think so...) if (indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) index = static_cast<unsigned long>(pLong[j]) + thisSectionStart; else index = static_cast<unsigned long>(pShort[j]) + thisSectionStart; returnIndices.push_back(index); } indexBuffer->unlock(); } } } //Now we simply return the data. index_count = returnIndices.size(); vertex_count = returnVertices.size(); vertices = new Ogre::Vector3[vertex_count]; for (unsigned long i = 0; i < vertex_count; ++i) vertices[i] = returnVertices[i]; indices = new unsigned long[index_count]; for (unsigned long i = 0; i < index_count; ++i) indices[i] = returnIndices[i]; //All done. return; }
mesh::mesh(const std::string &mn, const mat4 &tf, const world &_world): /** Don't know if world() is the best thing to pass but it works for now **/ _mesh(NewtonMeshCreate(_world)) { Ogre::MeshPtr meshPtr; try { meshPtr = Ogre::MeshPtr(Ogre::MeshManager::getSingleton().load(mn, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)); } catch(...) { return; } const Ogre::Mesh &mesh = *meshPtr; NewtonMeshBeginFace(_mesh); for (unsigned smi = 0; smi < mesh.getNumSubMeshes(); smi++) { Ogre::SubMesh *subMesh = mesh.getSubMesh(smi); Ogre::VertexData *vertexData = (subMesh->useSharedVertices) ? vertexData = mesh.sharedVertexData : vertexData = subMesh->vertexData; Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration; const Ogre::VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vertexHVBSP = vertexData->vertexBufferBinding->getBuffer(element->getSource()); unsigned char *vPtr = (unsigned char*)(vertexHVBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::IndexData *indexData = subMesh->indexData; size_t numIndices = indexData->indexCount; size_t numTris = numIndices / 3; // get pointer! Ogre::HardwareIndexBufferSharedPtr indexHIBSP = indexData->indexBuffer; // 16 or 32 bit indices? bool indicesAre32Bit = (indexHIBSP->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long *longPtr = NULL; unsigned short *shortPtr = NULL; if (indicesAre32Bit) longPtr = static_cast<unsigned long*>( indexHIBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else shortPtr = static_cast<unsigned short*>( indexHIBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); //now loop through the indices, getting polygon info! int iOffset = 0; for (size_t i = 0; i < numTris; i++) { vec3 triVertices[3]; unsigned char *vOffset = NULL; float *vertexPosPtr = NULL; int idx = 0; for (int j = 0; j < 3; j++) { if (indicesAre32Bit) idx = longPtr[iOffset + j]; else idx = shortPtr[iOffset + j]; vOffset = vPtr + (idx * vertexHVBSP->getVertexSize()); element->baseVertexPointerToElement(vOffset, &vertexPosPtr); triVertices[j].x = *vertexPosPtr; vertexPosPtr++; triVertices[j].y = *vertexPosPtr; vertexPosPtr++; triVertices[j].z = *vertexPosPtr; vertexPosPtr++; triVertices[j] = tf * triVertices[j]; } // _mesh, 3 vertices (triangle), (float = 4 bytes) * 3 // index = index of sub mesh (easy to recognize) NewtonMeshAddFace(_mesh, 3, &triVertices[0].x, sizeof(float) * 3, smi); iOffset += 3; } //unlock the buffers! vertexHVBSP->unlock(); indexHIBSP->unlock(); } NewtonMeshEndFace(_mesh); }
btTriangleMesh* GameLibrary::ogreToBulletMesh(Ogre::MeshPtr mesh) { btTriangleMesh* btMesh = new btTriangleMesh(); Ogre::Mesh::SubMeshIterator j = mesh->getSubMeshIterator(); while (j.hasMoreElements()) { Ogre::SubMesh* submesh = j.getNext(); int idxStart = submesh->indexData->indexStart; int nIdx = submesh->indexData->indexCount; Ogre::HardwareIndexBuffer* idxBuffer = submesh->indexData->indexBuffer.get(); Ogre::HardwareVertexBufferSharedPtr virtBuffer; Ogre::VertexDeclaration* virtDecl; if (submesh->useSharedVertices) { virtDecl = mesh->sharedVertexData->vertexDeclaration; assert(mesh->sharedVertexData->vertexBufferBinding->getBufferCount() > 0); virtBuffer = mesh->sharedVertexData->vertexBufferBinding->getBuffer(0); } else { virtDecl = submesh->vertexData->vertexDeclaration; assert(submesh->vertexData->vertexBufferBinding->getBufferCount() > 0); virtBuffer = submesh->vertexData->vertexBufferBinding->getBuffer(0); } unsigned char* pVert = static_cast<unsigned char*>(virtBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // need to lock the buffer since vertex data resides on GPU // and we need synchronization unsigned short* sindices = NULL; unsigned long* lindices = NULL; if (idxBuffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT) { sindices = static_cast<unsigned short*>(idxBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); } else if (idxBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) { lindices = static_cast<unsigned long*>(idxBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); } else { assert(true == false); } const Ogre::VertexElement* elm = virtDecl->findElementBySemantic(Ogre::VES_POSITION, 0); int offset = elm->getOffset(); // assert(elm->getType() == VET_FLOAT3); for (int k = idxStart; k < idxStart + nIdx; k += 3) { unsigned int indices[3]; btVector3 vertices[3]; if (idxBuffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT) { for (int l = 0; l < 3; ++l) { indices[l] = sindices[k + l]; } } else { for (int l = 0; l < 3; ++l) { indices[l] = lindices[k + l]; } } for (int l = 0; l < 3; ++l) { // for each vertex Ogre::Real* posVert = (Ogre::Real*)(pVert + indices[l] * virtBuffer->getVertexSize() + offset); for (int m = 0; m < 3; ++m) { // for each vertex component vertices[l][m] = posVert[m]; } } btMesh->addTriangle(vertices[0], vertices[1], vertices[2]); } idxBuffer->unlock(); virtBuffer->unlock(); } return btMesh; }
void PolyMousePicker::GetMeshInformation( Ogre::Entity *entity, size_t &vertex_count, Ogre::Vector3* &vertices, size_t &index_count, Ogre::uint32* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient, const Ogre::Vector3 &scale) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertex_count = index_count = 0; Ogre::MeshPtr mesh = entity->getMesh(); bool useSoftwareBlendingVertices = entity->hasSkeleton(); if (useSoftwareBlendingVertices) { entity->_updateAnimation(); } // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Ogre::Vector3[vertex_count]; indices = new Ogre::uint32[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); //---------------------------------------------------------------- // GET VERTEXDATA //---------------------------------------------------------------- Ogre::VertexData* vertex_data; //When there is animation: if(useSoftwareBlendingVertices) vertex_data = submesh->useSharedVertices ? entity->_getSkelAnimVertexData() : entity->getSubEntity(i)->_getSkelAnimVertexData(); else vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); void* hwBuf = ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; size_t index_start = index_data->indexStart; size_t last_index = numTris*3 + index_start; if (use32bitindexes) { Ogre::uint32* hwBuf32 = static_cast<Ogre::uint32*>(hwBuf); for (size_t k = index_start; k < last_index; ++k) { indices[index_offset++] = hwBuf32[k] + static_cast<Ogre::uint32>( offset ); } } else { Ogre::uint16* hwBuf16 = static_cast<Ogre::uint16*>(hwBuf); for (size_t k = index_start; k < last_index; ++k) { indices[ index_offset++ ] = static_cast<Ogre::uint32>( hwBuf16[k] ) + static_cast<Ogre::uint32>( offset ); } } ibuf->unlock(); current_offset = next_offset; } }