Beispiel #1
0
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 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());
		
	}
Beispiel #3
0
        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);
        }