//-----------------------------------------------------------------------
	void EntityRenderer::_prepare(ParticleTechnique* technique)
	{
		/** 
			- This renderer is a ´hacky´ solution to display geometry-based particles. It pre-creates a 
			number of SceneNodes (childs of the parent Node to which the ParticleSystem is attached) and 
			Entities and uses these pools to display the particles. There are better solutions, but 
			this one is simple and fast enough, although it has some drawbacks.
			- Future solutions should rather make use of hardware instancing to display a large number of
			geometry-based particles at once.
		*/

		// Use the given technique, although it should be the same as mParentTechnique (must be set already)
		if (!technique || mRendererInitialised)
			return;

		std::stringstream ss; 
		ss << this;
		mEntityName = mMeshName + ss.str();
		mQuota = technique->getVisualParticleQuota();
		Ogre::SceneNode* parentNode = technique->getParentSystem()->getParentSceneNode();
		Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(mMeshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		Ogre::Mesh* meshPointer = mesh.getPointer();
		Vector3 size = meshPointer->getBounds().getSize();
		mBoxWidth = size.x == 0.0f ? 1.0f : size.x;
		mBoxHeight = size.y == 0.0f ? 1.0f : size.y;
		mBoxDepth = size.z == 0.0f ? 1.0f : size.z;

		if (parentNode)
		{
			// Create number of VisualData objects including SceneNodes
			String sceneNodeName;
			for (size_t i = 0; i < mQuota; i++)
			{
				sceneNodeName = "ParticleUniverse" + ss.str() + StringConverter::toString(i);
				EntityRendererVisualData* visualData = 
					PU_NEW_T(EntityRendererVisualData, MEMCATEGORY_SCENE_OBJECTS)(parentNode->createChildSceneNode(sceneNodeName));

				mAllVisualData.push_back(visualData); // Managed by this renderer
				mVisualData.push_back(visualData); // Used to assign to a particle
			}

			// Create number of Entities
			Ogre::Entity* entity = technique->getParentSystem()->getSceneManager()->createEntity(mEntityName, mMeshName); // Base entity
			vector<EntityRendererVisualData*>::const_iterator it;
			vector<EntityRendererVisualData*>::const_iterator itEnd = mAllVisualData.end();
			size_t j;
			for (it = mAllVisualData.begin(), j = 0; it != itEnd; ++it, ++j)
			{
				Ogre::Entity* clonedEntity = entity->clone(mEntityName + StringConverter::toString(j));
				clonedEntity->setMaterialName(technique->getMaterialName());
				clonedEntity->setRenderQueueGroup(mQueueId);
				mEntities.push_back(clonedEntity);
				(*it)->node->attachObject(clonedEntity);
			}
			technique->getParentSystem()->getSceneManager()->destroyEntity(mEntityName);
		}

		_makeNodesVisible(false);
		mRendererInitialised = true;
	}
Ejemplo n.º 2
0
void GraphicsResourceMesh::setMaterialNames(GraphicsResourceMesh* resourcePtr)
{
  Ogre::ResourcePtr meshResource = Ogre::MeshManager::getSingleton().getByName(resourcePtr->getID());
  Ogre::Mesh* meshPtr = static_cast<Ogre::Mesh *>(&*meshResource);
  Ogre::Mesh::SubMeshIterator currSubMeshIter = meshPtr->getSubMeshIterator();

  while (currSubMeshIter.hasMoreElements()) {
    Ogre::SubMesh *curSubMesh = currSubMeshIter.getNext();

    if (!OPTION_ENABLE_TEXTURES->as<bool>()) {
      curSubMesh->setMaterialName("BaseWhiteTexture");
    }
    else {
      const Ogre::String& curMatName = curSubMesh->getMaterialName();
      int pos = curMatName.find_last_of(':');
      if (pos != -1) {
        String start = curMatName.substr(0, pos);
        String ending = curMatName.substr(pos);
        std::map<String, String>::iterator itr = resourcePtr->mMaterialNames.find(start);
        if (itr != resourcePtr->mMaterialNames.end())
          curSubMesh->setMaterialName(itr->second + ending);
      }
    }
  }
}
Ejemplo n.º 3
0
void NIFMeshLoader::loadResource(Ogre::Resource *resource)
{
    Ogre::Mesh *mesh = dynamic_cast<Ogre::Mesh*>(resource);
    OgreAssert(mesh, "Attempting to load a mesh into a non-mesh resource!");

    Nif::NIFFile::ptr nif = Nif::NIFFile::create(mName);
    if(mShapeIndex >= nif->numRecords())
    {
        Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
        if(!skelMgr->getByName(mName).isNull())
            mesh->setSkeletonName(mName);
        return;
    }

    const Nif::Record *record = nif->getRecord(mShapeIndex);
    createSubMesh(mesh, dynamic_cast<const Nif::NiTriShape*>(record));
}
Ejemplo n.º 4
0
bool EC_Mesh::SetAttachmentMesh(uint index, const std::string& mesh_name, const std::string& attach_point, bool share_skeleton)
{
    if (!ViewEnabled())
        return false;
    OgreWorldPtr world = world_.lock();

    if (!entity_)
    {
        LogError("EC_Mesh::SetAttachmentMesh: No mesh entity created yet, can not create attachments!");
        return false;
    }
    
    Ogre::SceneManager* sceneMgr = world->OgreSceneManager();
    
    size_t oldsize = attachment_entities_.size();
    size_t newsize = index + 1;
    
    if (oldsize < newsize)
    {
        attachment_entities_.resize(newsize);
        attachment_nodes_.resize(newsize);
        for(uint i = oldsize; i < newsize; ++i)
        {
            attachment_entities_[i] = 0;
            attachment_nodes_[i] = 0;
        }
    }
    
    RemoveAttachmentMesh(index);
    
    Ogre::Mesh* mesh = PrepareMesh(mesh_name, false);
    if (!mesh)
        return false;

    if (share_skeleton)
    {
        // If sharing a skeleton, force the attachment mesh to use the same skeleton
        // This is theoretically quite a scary operation, for there is possibility for things to go wrong
        Ogre::SkeletonPtr entity_skel = entity_->getMesh()->getSkeleton();
        if (entity_skel.isNull())
        {
            LogError("EC_Mesh::SetAttachmentMesh: Cannot share skeleton for attachment, not found");
            return false;
        }
        try
        {
            mesh->_notifySkeleton(entity_skel);
        }
        catch(const Ogre::Exception &/*e*/)
        {
            LogError("EC_Mesh::SetAttachmentMesh: Could not set shared skeleton for attachment");
            return false;
        }
    }

    try
    {
        QString entityName = QString("EC_Mesh_attach") + QString::number(index);
        attachment_entities_[index] = sceneMgr->createEntity(world->GetUniqueObjectName(entityName.toStdString()), mesh->getName());
        if (!attachment_entities_[index])
        {
            LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name);
            return false;
        }

        attachment_entities_[index]->setRenderingDistance(drawDistance.Get());
        attachment_entities_[index]->setCastShadows(castShadows.Get());
        attachment_entities_[index]->setUserAny(entity_->getUserAny());
        // Set UserAny also on subentities
        for(uint i = 0; i < attachment_entities_[index]->getNumSubEntities(); ++i)
            attachment_entities_[index]->getSubEntity(i)->setUserAny(entity_->getUserAny());

        Ogre::Bone* attach_bone = 0;
        if (!attach_point.empty())
        {
            Ogre::Skeleton* skel = entity_->getSkeleton();
            if (skel && skel->hasBone(attach_point))
                attach_bone = skel->getBone(attach_point);
        }
        if (attach_bone)
        {
            Ogre::TagPoint* tag = entity_->attachObjectToBone(attach_point, attachment_entities_[index]);
            attachment_nodes_[index] = tag;
        }
        else
        {
            QString nodeName = QString("EC_Mesh_attachment_") + QString::number(index);
            Ogre::SceneNode* node = sceneMgr->createSceneNode(world->GetUniqueObjectName(nodeName.toStdString()));
            node->attachObject(attachment_entities_[index]);
            adjustment_node_->addChild(node);
            attachment_nodes_[index] = node;
        }
        
        if (share_skeleton && entity_->hasSkeleton() && attachment_entities_[index]->hasSkeleton())
        {
            attachment_entities_[index]->shareSkeletonInstanceWith(entity_);
        }
    }
    catch(Ogre::Exception& e)
    {
        LogError("EC_Mesh::SetAttachmentMesh: Could not set attachment mesh " + mesh_name + ": " + std::string(e.what()));
        return false;
    }
    return true;
}
Ejemplo n.º 5
0
bool EC_Mesh::SetMeshWithSkeleton(const std::string& mesh_name, const std::string& skeleton_name, bool clone)
{
    if (!ViewEnabled())
        return false;
    OgreWorldPtr world = world_.lock();

    Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(AssetAPI::SanitateAssetRef(skeleton_name));
    if (skel.isNull())
    {
        LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": not found");
        return false;
    }
    
    RemoveMesh();

    Ogre::SceneManager* sceneMgr = world->OgreSceneManager();
    
    Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone);
    if (!mesh)
        return false;
    
    try
    {
        mesh->_notifySkeleton(skel);
//        LogDebug("Set skeleton " + skeleton_name + " to mesh " + mesh_name);
    }
    catch(Ogre::Exception& e)
    {
        LogError("EC_Mesh::SetMeshWithSkeleton: Could not set skeleton " + skeleton_name + " to mesh " + mesh_name + ": " + std::string(e.what()));
        return false;
    }
    
    try
    {
        entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entwithskel"), mesh->getName());
        if (!entity_)
        {
            LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name);
            return false;
        }
        
        entity_->setRenderingDistance(drawDistance.Get());
        entity_->setCastShadows(castShadows.Get());
        entity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this)));
        // Set UserAny also on subentities
        for(uint i = 0; i < entity_->getNumSubEntities(); ++i)
            entity_->getSubEntity(i)->setUserAny(entity_->getUserAny());
        
        if (entity_->hasSkeleton())
        {
            Ogre::SkeletonInstance* skel = entity_->getSkeleton();
            // Enable cumulative mode on skeletal animations
            if (skel)
                skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE);
        }
    }
    catch(Ogre::Exception& e)
    {
        LogError("EC_Mesh::SetMeshWithSkeleton: Could not set mesh " + mesh_name + ": " + std::string(e.what()));
        return false;
    }
    
    AttachEntity();
    
    emit MeshChanged();
    
    return true;
}
Ejemplo n.º 6
0
bool EC_Mesh::SetMesh(QString meshResourceName, bool clone)
{
    if (!ViewEnabled())
        return false;
    
    OgreWorldPtr world = world_.lock();

    std::string mesh_name = meshResourceName.trimmed().toStdString();

    RemoveMesh();

    // If placeable is not set yet, set it manually by searching it from the parent entity
    if (!placeable_)
    {
        Entity* entity = ParentEntity();
        if (entity)
        {
            ComponentPtr placeable = entity->GetComponent(EC_Placeable::TypeNameStatic());
            if (placeable)
                placeable_ = placeable;
        }
    }
    
    Ogre::SceneManager* sceneMgr = world->OgreSceneManager();
    
    Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone);
    if (!mesh)
        return false;
    
    try
    {
        entity_ = sceneMgr->createEntity(world->GetUniqueObjectName("EC_Mesh_entity"), mesh->getName());
        if (!entity_)
        {
            LogError("EC_Mesh::SetMesh: Could not set mesh " + mesh_name);
            return false;
        }
        
        entity_->setRenderingDistance(drawDistance.Get());
        entity_->setCastShadows(castShadows.Get());
        entity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this)));
        // Set UserAny also on subentities
        for(uint i = 0; i < entity_->getNumSubEntities(); ++i)
            entity_->getSubEntity(i)->setUserAny(entity_->getUserAny());

        if (entity_->hasSkeleton())
        {
            Ogre::SkeletonInstance* skel = entity_->getSkeleton();
            // Enable cumulative mode on skeletal animations
            if (skel)
                skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE);
        }
        
        // Make sure adjustment node is uptodate
        Transform newTransform = nodeTransformation.Get();
        adjustment_node_->setPosition(newTransform.pos);
        adjustment_node_->setOrientation(newTransform.Orientation());
        
        // Prevent Ogre exception from zero scale
        adjustment_node_->setScale(Max(newTransform.scale, float3::FromScalar(0.0000001f)));
            
        // Force a re-apply of all materials to this new mesh.
        ApplyMaterial();
    }
    catch(Ogre::Exception& e)
    {
        LogError("EC_Mesh::SetMesh: Could not set mesh " + mesh_name + ": " + std::string(e.what()));
        return false;
    }
    
    AttachEntity();
    emit MeshChanged();
    
    return true;
}
Ejemplo n.º 7
0
	Mesh* OgreSubsystem::createMesh(const MeshData& data,String name)
	{
		 String nombre = name;
		if(name=="AUTO_NAME_ME")
		{
			nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex);
			++mAutoNameIndex;
		}

		using namespace Ogre;

		bool hasVertexColor = data.getDiffuse();
		bool hasNormals = data.getNormals();

		int numFaces = data.indices.size()/3;
		int numVertices = data.vertices.size()/3;

		HardwareVertexBufferSharedPtr posVertexBuffer;
		HardwareVertexBufferSharedPtr normVertexBuffer;
		std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer;
		HardwareVertexBufferSharedPtr diffuseVertexBuffer;
		HardwareIndexBufferSharedPtr indexBuffer;

		Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual(
		nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get();

		Ogre::SubMesh* sm = m->createSubMesh();
		sm->useSharedVertices = false;
		sm->vertexData = new VertexData();
		sm->vertexData->vertexStart = 0;
		sm->vertexData->vertexCount = numVertices;

		Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration;
		Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding;

		size_t bufferCount = 0;

		vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION);

		if(hasNormals)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL);

		if(hasVertexColor)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE);

		for(int i=0;i<data.texcoords.size();++i)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i);

		bufferCount = 0;

		// Positions
		posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

		vbind->setBinding(bufferCount, posVertexBuffer);

		float* vertices = data.getVertices();
		float* normals = data.getNormals();
		float* diffuse = data.getDiffuse();
		unsigned short* indices = data.getIndices();

		posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true);

		// Normals
		if(hasNormals)
		{
			normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

			vbind->setBinding(++bufferCount, normVertexBuffer);

			normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true);
		}

		if(hasVertexColor)
		{
			diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			vbind->setBinding(++bufferCount, diffuseVertexBuffer);

			diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true);
		}

		// Texcoords
		for(int i=0;i<data.texcoords.size();++i)
		{
			texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer(
			2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY));

			vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]);

			texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false);
		}

		if(!data.indices.empty())
		{
			// Prepare buffer for indices
			indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);

			//unsigned short *faceVertexIndices = (unsigned short*)
			//indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD);

			// Set index buffer for this submesh
			sm->indexData->indexBuffer = indexBuffer;
			sm->indexData->indexStart = 0;
			sm->indexData->indexCount = 3*numFaces;

			indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true);
		}

		//vdecl->sort();

		m->load();
		m->touch();

		m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2],
        data.bbox[3],data.bbox[4],data.bbox[5]), false);

		sm->setMaterialName("Terrain");

		Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName());
		Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre);
		node->attachObject(ent);
		ent->setCastShadows(false);
		Mesh* mm = new Mesh(nombre,node,ent);
		mSceneNodes.push_back(mm);
		return mm;
	}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
bool EC_Mesh::SetMesh(QString meshResourceName, bool clone)
{
    if (!ViewEnabled())
        return false;
    
    if (renderer_.expired())
        return false;
    RendererPtr renderer = renderer_.lock();

    std::string mesh_name = meshResourceName.trimmed().toStdString();

    RemoveMesh();

    // If placeable is not set yet, set it manually by searching it from the parent entity
    if (!placeable_)
    {
        Scene::Entity* entity = GetParentEntity();
        if (entity)
        {
            ComponentPtr placeable = entity->GetComponent(EC_Placeable::TypeNameStatic());
            if (placeable)
                placeable_ = placeable;
        }
    }
    
    Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
    
    Ogre::Mesh* mesh = PrepareMesh(mesh_name, clone);
    if (!mesh)
        return false;
    
    try
    {
        entity_ = scene_mgr->createEntity(renderer->GetUniqueObjectName("EC_Mesh_entity"), mesh->getName());
        if (!entity_)
        {
            LogError("Could not set mesh " + mesh_name);
            return false;
        }
        
        entity_->setRenderingDistance(drawDistance.Get());
        entity_->setCastShadows(castShadows.Get());
        entity_->setUserAny(Ogre::Any(GetParentEntity()));
        // Set UserAny also on subentities
        for (uint i = 0; i < entity_->getNumSubEntities(); ++i)
            entity_->getSubEntity(i)->setUserAny(entity_->getUserAny());
                
        if (entity_->hasSkeleton())
        {
            Ogre::SkeletonInstance* skel = entity_->getSkeleton();
            // Enable cumulative mode on skeletal animations
            if (skel)
                skel->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE);
        }
        
        // Make sure adjustment node is uptodate
        if (adjustment_node_)
        {
            Transform newTransform = nodeTransformation.Get();
            adjustment_node_->setPosition(newTransform.position.x, newTransform.position.y, newTransform.position.z);
            Quaternion adjust(DEGTORAD * newTransform.rotation.x,
                            DEGTORAD * newTransform.rotation.y,
                            DEGTORAD * newTransform.rotation.z);
            adjustment_node_->setOrientation(Ogre::Quaternion(adjust.w, adjust.x, adjust.y, adjust.z));
            
            // Prevent Ogre exception from zero scale
            if (newTransform.scale.x < 0.0000001f)
                newTransform.scale.x = 0.0000001f;
            if (newTransform.scale.y < 0.0000001f)
                newTransform.scale.y = 0.0000001f;
            if (newTransform.scale.z < 0.0000001f)
                newTransform.scale.z = 0.0000001f;

            adjustment_node_->setScale(newTransform.scale.x, newTransform.scale.y, newTransform.scale.z);
        }

        // Force a re-apply of all materials to this new mesh.
        ApplyMaterial();
    }
    catch (Ogre::Exception& e)
    {
        LogError("Could not set mesh " + mesh_name + ": " + std::string(e.what()));
        return false;
    }
    
    AttachEntity();
    emit MeshChanged();
    
    return true;
}