Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include <rve_render_server/mesh_instance.h>
00031 #include <rve_render_server/mesh.h>
00032 #include <rve_render_server/submesh.h>
00033 #include <rve_render_server/material.h>
00034 #include <rve_render_server/init.h>
00035 #include <rve_render_server/renderer.h>
00036 
00037 #include <OGRE/OgreSceneManager.h>
00038 #include <OGRE/OgreEntity.h>
00039 #include <OGRE/OgreSubEntity.h>
00040 #include <OGRE/OgreSceneNode.h>
00041 
00042 #include <ros/types.h>
00043 #include <ros/console.h>
00044 #include <ros/assert.h>
00045 
00046 namespace rve_render_server
00047 {
00048 
00049 MeshInstance::MeshInstance(const rve_common::UUID& id, Ogre::SceneManager* scene_manager, const MeshPtr& mesh)
00050 : Renderable(id)
00051 , scene_manager_(scene_manager)
00052 , mesh_(mesh)
00053 {
00054   std::stringstream ss;
00055   static size_t count = 0;
00056   ss << "MeshInstance" << count++;
00057 
00058   entity_ = scene_manager_->createEntity(ss.str(), mesh->getID().toString());
00059   scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00060   scene_node_->attachObject(entity_);
00061 
00062   pick_id_ = getRenderer()->allocatePickID(this);
00063   Ogre::Vector4 pick_color(intToFloat4<Ogre::Vector4>(pick_id_));
00064 
00065   for (size_t i = 0; i < mesh->getSubMeshCount(); ++i)
00066   {
00067     rve_common::UUID mat_id = mesh->getSubMesh(i)->getMaterialID();
00068     entity_->getSubEntity(i)->setCustomParameter(Material::CustomParam_ObjectID, pick_color);
00069 
00070     if (!mat_id.isNull())
00071     {
00072       MaterialPtr mat = getRenderer()->getMaterial(mat_id);
00073       setMaterial(i, mat);
00074     }
00075   }
00076 }
00077 
00078 MeshInstance::~MeshInstance()
00079 {
00080   M_Material::iterator it = mat_to_subs_.begin();
00081   M_Material::iterator end = mat_to_subs_.end();
00082   for (; it != end; ++it)
00083   {
00084     it->first->detachRenderable(this);
00085   }
00086 
00087   scene_manager_->destroyEntity(entity_);
00088   scene_manager_->destroySceneNode(scene_node_);
00089 
00090   getRenderer()->deallocatePickID(pick_id_);
00091 }
00092 
00093 void MeshInstance::setMaterial(const MaterialPtr& mat)
00094 {
00095   M_Material::iterator it = mat_to_subs_.begin();
00096   M_Material::iterator end = mat_to_subs_.end();
00097   for (; it != end; ++it)
00098   {
00099     it->first->detachRenderable(this);
00100   }
00101 
00102   mat_to_subs_.clear();
00103 
00104   if (mat)
00105   {
00106     for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i)
00107     {
00108       Ogre::SubEntity* sub = entity_->getSubEntity(i);
00109       mat_to_subs_[mat].insert(sub);
00110       sub_to_mat_[sub] = mat;
00111 
00112       mat->attachRenderable(this, sub);
00113     }
00114   }
00115 }
00116 
00117 void MeshInstance::setMaterial(size_t submesh_index, const MaterialPtr& mat)
00118 {
00119   ROS_ASSERT(submesh_index < entity_->getNumSubEntities());
00120   Ogre::SubEntity* sub = entity_->getSubEntity(submesh_index);
00121   M_SubEntityToMaterial::iterator subent_it = sub_to_mat_.find(sub);
00122   if (subent_it != sub_to_mat_.end())
00123   {
00124     const MaterialPtr& old_mat = subent_it->second;
00125     mat_to_subs_[old_mat].erase(sub);
00126   }
00127 
00128   sub_to_mat_[sub] = mat;
00129   mat_to_subs_[mat].insert(sub);
00130   mat->attachRenderable(this, sub);
00131 }
00132 
00133 void MeshInstance::onOgreMaterialChanged(const MaterialPtr& mat)
00134 {
00135   M_Material::iterator it = mat_to_subs_.find(mat);
00136   if (it != mat_to_subs_.end())
00137   {
00138     const MaterialPtr& mat = it->first;
00139     S_OgreSubEntity::iterator sub_it = it->second.begin();
00140     S_OgreSubEntity::iterator sub_end = it->second.end();
00141     for (; sub_it != sub_end; ++sub_it)
00142     {
00143       Ogre::SubEntity* sub = *sub_it;
00144       sub->setMaterial(mat->getOgreMaterial());
00145     }
00146   }
00147 }
00148 
00149 Picked MeshInstance::translatePick(PickRenderValues id)
00150 {
00151   ROS_ASSERT(id.id == pick_id_);
00152   return Picked(getID(), 0);
00153 }
00154 
00155 }