Exemplo n.º 1
0
	//------------------------------------------------------------------------------------------------
	void StaticMeshToShapeConverter::addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform)
	{
		// Each entity added need to reset size and radius
		// next time getRadius and getSize are asked, they're computed.
		mBounds  = Ogre::Vector3(-1,-1,-1);
		mBoundRadius = -1;

		//_entity = entity;
		//_node = (SceneNode*)(_entity->getParentNode());
		mTransform = transform;

		if (mesh->hasSkeleton ())
			Ogre::LogManager::getSingleton().logMessage("MeshToShapeConverter::addMesh : Mesh " + mesh->getName () + " as skeleton but added to trimesh non animated");

		if (mesh->sharedVertexData)
		{
			VertexIndexToShape::addStaticVertexData (mesh->sharedVertexData);
		}

		for(unsigned int i = 0;i < mesh->getNumSubMeshes();++i)
		{
			Ogre::SubMesh *sub_mesh = mesh->getSubMesh(i);

			if (!sub_mesh->useSharedVertices)
			{
				VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);
				VertexIndexToShape::addStaticVertexData (sub_mesh->vertexData);
			}
			else
			{
				VertexIndexToShape::addIndexData (sub_mesh->indexData);
			}

		}
	}
Exemplo n.º 2
0
std::pair<int, int> MeshUtils::getMeshCount(const Ogre::MeshPtr& mesh)
{
	size_t vertex_count = 0;
	size_t index_count = 0;
	bool added_shared = false;

	for (int j = 0; j < mesh->getNumSubMeshes(); j++) {
			Ogre::SubMesh* submesh = mesh->getSubMesh(j);

//			VertexData* vertex_data = submesh->vertexData;
//			IndexData* index_data = submesh->indexData;

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

	return std::make_pair(vertex_count, index_count);
}
Exemplo n.º 3
0
 void LodInputBuffer::fillBuffer( Ogre::MeshPtr mesh )
 {
     meshName = mesh->getName();
     boundingSphereRadius = mesh->getBoundingSphereRadius();
     bool sharedVerticesAdded = false;
     unsigned short submeshCount = mesh->getNumSubMeshes();
     submesh.resize(submeshCount);
     for (unsigned short i = 0; i < submeshCount; i++) {
         const SubMesh* ogresubmesh = mesh->getSubMesh(i);
         LodInputBuffer::Submesh& outsubmesh = submesh[i];
         outsubmesh.indexBuffer.fillBuffer(ogresubmesh->indexData);
         outsubmesh.useSharedVertexBuffer = ogresubmesh->useSharedVertices;
         if (!outsubmesh.useSharedVertexBuffer) {
             outsubmesh.vertexBuffer.fillBuffer(ogresubmesh->vertexData);
         } else if (!sharedVerticesAdded) {
             sharedVerticesAdded = true;
             sharedVertexBuffer.fillBuffer(mesh->sharedVertexData);
         }
     }
 }
//------------------------------------------------------------------------------------------------
void AnimatedMeshToShapeConverter::addMesh(const Ogre::MeshPtr &mesh,
                                           const Ogre::Matrix4 &transform)
{
    // Each entity added need to reset size and radius
    // next time getRadius and getSize are asked, they're computed.
    mBounds = Ogre::Vector3(-1.0f , -1.0f, -1.0f);
    mBoundRadius = -1.0f;

    //_entity = entity;
    //_node = (SceneNode*)(_entity->getParentNode());
    mTransform = transform;

    assert(mesh->hasSkeleton());

    if (mesh->sharedVertexData)
    {
        VertexIndexToShape::addAnimatedVertexData(mesh->sharedVertexData,
                                                  NULL,
                                                  &mesh->sharedBlendIndexToBoneIndexMap);
    }

    for (unsigned int i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh *sub_mesh = mesh->getSubMesh(i);

        if (!sub_mesh->useSharedVertices)
        {
            VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount);

            VertexIndexToShape::addAnimatedVertexData(sub_mesh->vertexData,
                                                      NULL,
                                                      &sub_mesh->blendIndexToBoneIndexMap);
        }
        else 
        {
            VertexIndexToShape::addIndexData(sub_mesh->indexData);
        }
    }
}
Exemplo n.º 5
0
	//---------------------------------------------------------------------
	void MeshElement::setMaterialName(const String &name)
	{
		mMaterialName = name;

		if (mEntity)
		{
			// if this is "none",we will use the origin material of the mesh
			if (mMaterialName == "none")
			{

				if ( false == mMeshName.empty() )
				{
					Ogre::MeshPtr currentMesh = Ogre::MeshManager::getSingleton().getByName(mMeshName);

					for ( unsigned short i=0; i<currentMesh->getNumSubMeshes(); ++i )
					{
						mEntity->getSubEntity(i)->setMaterialName( currentMesh->getSubMesh(i)->getMaterialName() );
					}
				}
			}		
			else
				mEntity->setMaterialName(mMaterialName);
		}		
	}
Exemplo n.º 6
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.º 7
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;
	}
}
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);
    }
}
	//-----------------------------------------------------------------------
	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.º 10
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.º 11
0
	//---------------------------------------------------------------------
	void OptimiseTool::processMesh(Ogre::MeshPtr mesh)
	{
		bool rebuildEdgeList = false;
		// Shared geometry
		if (mesh->sharedVertexData)
		{
			print("Optimising mesh shared vertex data...");
			setTargetVertexData(mesh->sharedVertexData);

			for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
			{
				SubMesh* sm = mesh->getSubMesh(i);
				if (sm->useSharedVertices)
				{
					addIndexData(sm->indexData);
				}
			}

			if (optimiseGeometry())
			{
				if (mesh->getSkeletonName() != StringUtil::BLANK)
				{
					print("    fixing bone assignments...");
					Mesh::BoneAssignmentIterator currentIt = mesh->getBoneAssignmentIterator();
					Mesh::VertexBoneAssignmentList newList =
						getAdjustedBoneAssignments(currentIt);
					mesh->clearBoneAssignments();
					for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
						bi != newList.end(); ++bi)
					{
						mesh->addBoneAssignment(bi->second);
					}

				}

				for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
				{
					SubMesh* sm = mesh->getSubMesh(i);
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}
					if (sm->useSharedVertices)
					{
						fixLOD(sm->mLodFaceList);
					}
				}
				rebuildEdgeList = true;

			}
		}

		// Dedicated geometry
		for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
		{
			SubMesh* sm = mesh->getSubMesh(i);
			if (!sm->useSharedVertices)
			{
				print("Optimising submesh " +
					StringConverter::toString(i) + " dedicated vertex data ");
				setTargetVertexData(sm->vertexData);
				addIndexData(sm->indexData);
				if (optimiseGeometry())
				{
					if (mesh->getSkeletonName() != StringUtil::BLANK)
					{
						print("    fixing bone assignments...");
						Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator();
						Mesh::VertexBoneAssignmentList newList =
							getAdjustedBoneAssignments(currentIt);
						sm->clearBoneAssignments();
						for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin();
							bi != newList.end(); ++bi)
						{
							sm->addBoneAssignment(bi->second);
						}

					}

					fixLOD(sm->mLodFaceList);
					rebuildEdgeList = true;
				}
			}
		}

		if (rebuildEdgeList && mesh->isEdgeListBuilt())
		{
			// force rebuild of edge list
			mesh->freeEdgeList();
			mesh->buildEdgeList();
		}


	}
Exemplo n.º 12
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.º 13
0
OgreNewt::ConvexCollisionPtr PhysicsRagDoll::RagBone::_makeConvexHull(OgreNewt::World* world, Ogre::MeshPtr mesh, Ogre::Real minWeight)
{
	std::vector< Ogre::Vector3 > vertexVector;

	// for this bone, gather all of the vertices linked to it, and make an individual convex hull.
	std::string boneName = mOgreBone->getName();
	unsigned int boneIndex = mOgreBone->getHandle();

	Ogre::Matrix4 invMatrix;
	invMatrix.makeInverseTransform(-mOgreBone->_getBindingPoseInversePosition(), Ogre::Vector3::UNIT_SCALE / mOgreBone->_getBindingPoseInverseScale(), mOgreBone->_getBindingPoseInverseOrientation().Inverse());

	unsigned int num_sub = mesh->getNumSubMeshes();

	for (unsigned int i = 0; i < num_sub; i++)
	{
		Ogre::SubMesh* submesh = mesh->getSubMesh(i);
		Ogre::SubMesh::BoneAssignmentIterator bai = submesh->getBoneAssignmentIterator();

		Ogre::VertexDeclaration* v_decl;
		const Ogre::VertexElement* p_elem;
		float* v_Posptr;
		size_t v_count;
		Ogre::VertexData* v_data = NULL;

		if (submesh->useSharedVertices)
		{
			v_data = mesh->sharedVertexData;
			v_count = v_data->vertexCount;
			v_decl = v_data->vertexDeclaration;
			p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION);
		}
		else
		{
			v_data = submesh->vertexData;
			v_count = v_data->vertexCount;
			v_decl = v_data->vertexDeclaration;
			p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION);
		}		
			
		size_t start = v_data->vertexStart;
		//pointer
		Ogre::HardwareVertexBufferSharedPtr v_sptr = v_data->vertexBufferBinding->getBuffer(p_elem->getSource());
		unsigned char* v_ptr = static_cast<unsigned char*>(v_sptr->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
		unsigned char* v_offset;
		
		while (bai.hasMoreElements())
		{
			Ogre::VertexBoneAssignment vba = bai.getNext();
			if (vba.boneIndex == boneIndex)
			{
				//found a vertex that is attached to this bone.
				if (vba.weight >= minWeight)
				{
					//get offset to Position data!
					v_offset = v_ptr + (vba.vertexIndex * v_sptr->getVertexSize());
					p_elem->baseVertexPointerToElement(v_offset, &v_Posptr);

					Ogre::Vector3 vert;
					vert.x = *v_Posptr; v_Posptr++;
					vert.y = *v_Posptr; v_Posptr++;
					vert.z = *v_Posptr; 

					// apply transformation in to local space.
					vert = invMatrix * vert;

					vertexVector.push_back(vert);

					Ogre::LogManager::getSingletonPtr()->logMessage("  vertex found! id:"+Ogre::StringConverter::toString(vba.vertexIndex));
				}
			}

		}

		v_sptr->unlock();

	}
		

	// okay, we have gathered all verts for this bone.  make a convex hull!
	unsigned int numVerts = vertexVector.size();
	Ogre::Vector3* verts = new Ogre::Vector3[ numVerts ];
	unsigned int j = 0;
	while (!vertexVector.empty())
	{
		verts[j] = vertexVector.back();
		vertexVector.pop_back();
		j++;
	}

	//////////////////////////////////////////////////////////////////////////////////
    OgreNewt::ConvexCollisionPtr col;
    if (numVerts > 0)
    	col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::ConvexHull(world, verts, numVerts, 0));

	delete []verts;

	return col;	
}
Exemplo n.º 14
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.º 15
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;
    }
}
Exemplo n.º 16
0
    //-----------------------------------------------------------------------
    void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh)
    {
        // Retrieve data to copy bone assignments
        const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments();
        Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin();
        Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end();
        size_t curVertexOffset = 0;

        // Access shared vertices
        VertexData* sharedVertexData = mesh->sharedVertexData;

        for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++)
        {
            SubMesh *subMesh = mesh->getSubMesh(subMeshIdx);

            IndexData *indexData = subMesh->indexData;
            HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType();
            IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices<uint16>(indexData) :
                                                                                 getUsedIndices<uint32>(indexData);


            VertexData *newVertexData = new VertexData();
            newVertexData->vertexCount = indicesMap.size();
            newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone();

            for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) 
            {
                HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx);
                size_t vertexSize = sharedVertexBuffer->getVertexSize();                

                HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer
                    (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer());

                uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY);
                uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL);

                IndicesMap::iterator indIt = indicesMap.begin();
                IndicesMap::iterator endIndIt = indicesMap.end();
                for (; indIt != endIndIt; ++indIt)
                {
                    memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize);
                }

                sharedVertexBuffer->unlock();
                newVertexBuffer->unlock();

                newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer);
            }

            if (idxType == HardwareIndexBuffer::IT_16BIT)
            {
                copyIndexBuffer<uint16>(indexData, indicesMap);
            }
            else
            {
                copyIndexBuffer<uint32>(indexData, indicesMap);
            }

            // Store new attributes
            subMesh->useSharedVertices = false;
            subMesh->vertexData = newVertexData;

            // Transfer bone assignments to the submesh
            size_t offset = curVertexOffset + newVertexData->vertexCount;
            for (; it != end; ++it)
            {
                size_t vertexIdx = (*it).first;
                if (vertexIdx > offset)
                    break;

                VertexBoneAssignment boneAssignment = (*it).second;
                boneAssignment.vertexIndex = static_cast<unsigned int>(boneAssignment.vertexIndex - curVertexOffset);
                subMesh->addBoneAssignment(boneAssignment);
            }
            curVertexOffset = newVertexData->vertexCount + 1;
        }

        // Release shared vertex data
        delete mesh->sharedVertexData;
        mesh->sharedVertexData = NULL;
        mesh->clearBoneAssignments();
    }
Exemplo n.º 17
0
void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale )
{
	//from mesh magick / mit licence
	 Nx::Matrix4 transform = Nx::Matrix4::IDENTITY;
	 Nx::Vector3 translate =  Nx::Vector3::ZERO;
	// Apply current transform to the mesh, to get the bounding box to
	// base te translation on.
	AxisAlignedBox aabb = getMeshAabb( mesh, transform);
	//if (alignment == "left")
	//{
	// 	translate = Vector3(-aabb.getMinimum().x, 0, 0);
	//}
	//else if (alignment == "center")
	//{
	//	translate = Vector3(-aabb.getCenter().x, 0, 0);
	//}
	//else if (alignment == "right")
	//{
	//	translate = Vector3(-aabb.getMaximum().x, 0, 0);
	//}

	//Position .. only support pivot down / centered
	//translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down

	translate = Position;
	 
	transform = Nx::Matrix4::getTrans(translate) * transform;

	//rotation
	transform = Nx::Matrix4(Rotation) * transform;

	//scale
	transform = Nx::Matrix4::getScale(Scale) * transform;

    // Check whether we have to flip vertex winding.
    // We do have to, if we changed our right hand base.
    // We can test it by using the cross product from X and Y and see, if it is a non-negative
    // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet,
    // but the test is cheap either way.
    Nx::Matrix3 m3;
    transform.extract3x3Matrix(m3);

    if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
    {
		LogMsg("SetPivotPosition : Flipping vertex winding ... "   );
    	mFlipVertexWinding = true;
    }

	//mTransform = transform;

	NxMat4toOgre( mTransform, transform ) ;


	mBoundingBox.setNull();

    if( mesh->sharedVertexData != NULL)
    {
        processVertexData( mesh->sharedVertexData);
	}else
	{
		LogMsg("mesh->sharedVertexData NULL");
	}

    for( int i = 0; i < mesh->getNumSubMeshes(); i++ )
    {
        SubMesh* submesh = mesh->getSubMesh(i);
        if( submesh->vertexData != NULL )
        {
			LogMsg("SetPivotPosition : Processing vertex data ... "   );
            processVertexData(submesh->vertexData);
		}else
		{
			LogMsg("submesh->vertexData NULL");
		}

        if (submesh->indexData != NULL)
        {
			LogMsg("SetPivotPosition : Processing Index data .."   );
        	processIndexData(submesh->indexData);
		}else
		{
			LogMsg("submesh->indexData NULL");
		}
    }

	//process pose
    for( unsigned short i = 0; i < mesh->getPoseCount(); ++i )
    {
		Ogre::Pose * pose =  mesh->getPose(i);
		Ogre::Matrix3 m3x3;
		mTransform.extract3x3Matrix(m3x3);

		Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator();
		while (it.hasMoreElements()) {
			Ogre::Vector3 offset = it.peekNextValue();
			Ogre::Vector3 newOffset = m3x3 * offset;
			*it.peekNextValuePtr() = newOffset;
			it.moveNext();
		}
    }

	mesh->_setBounds( mBoundingBox, false );
  
}
Exemplo n.º 18
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;
    }
  }