Exemplo n.º 1
0
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();
    }
}
Exemplo n.º 3
0
//-------------------------------------------------------
// 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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
	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");
}
Exemplo n.º 8
0
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);
    }
}
Exemplo n.º 9
0
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;
		}
}
Exemplo n.º 10
0
	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());
	}
Exemplo n.º 12
0
    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;
        }
    }
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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();
    }
}
Exemplo n.º 18
0
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];
}
Exemplo n.º 19
0
// 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();
    }
}
Exemplo n.º 21
0
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;
    }
  }
}
Exemplo n.º 22
0
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();
    }
}
Exemplo n.º 23
0
        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;
        }
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
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);
        }
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
  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;
    }
  }