MeshManager.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00023 #include <wx/wx.h>
00024 #include <wx/platform.h>
00025 
00026 #include <GL/glew.h>
00027 
00028 #ifdef __WXMAC__
00029 #include <OpenGL/gl.h>
00030 #else
00031 #ifdef __WXMSW__
00032 #include <vigra/windows.h>
00033 #endif
00034 #include <GL/gl.h>
00035 #endif
00036 
00037 #include "panoinc.h"
00038 #include "ViewState.h"
00039 #include "MeshManager.h"
00040 #include "ChoosyRemapper.h"
00041 #include "LayoutRemapper.h"
00042 #include <iostream>
00043 
00044 
00045 // If we want to draw the outline of each face instead of shading it normally,
00046 // uncomment this. Wireframe mode is for testing mesh quality.
00047 // #define WIREFRAME
00048 
00049 const double MeshManager::PanosphereOverviewMeshInfo::scale_diff=1.5;
00050 
00051 MeshManager::MeshManager(HuginBase::Panorama *pano, VisualizationState *visualization_state)
00052     :   m_pano(pano),
00053         visualization_state(visualization_state),
00054         layout_mode_on(false)
00055 {
00056 }
00057 
00058 MeshManager::~MeshManager()
00059 {
00060     for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
00061         delete (*it);
00062     }
00063     meshes.clear();
00064 }
00065 
00066 void MeshManager::CheckUpdate()
00067 {
00068     unsigned int old_size = meshes.size();    
00069     // Resize to fit if images were removed
00070     while (meshes.size() > m_pano->getNrOfImages())
00071     {
00072         delete (meshes[meshes.size()-1]);
00073         meshes.pop_back();
00074     }
00075     // check each existing image individualy.
00076     for (unsigned int i = 0; i < meshes.size(); i++)
00077     {
00078         if (visualization_state->RequireRecalculateMesh(i))
00079         {
00080             DEBUG_DEBUG("Update mesh for " << i);
00081             meshes[i]->SetSrcImage(visualization_state->GetSrcImage(i));
00082             meshes[i]->Update();
00083         }
00084     }
00085     // add any new images.
00086     for (unsigned int i = old_size; i < m_pano->getNrOfImages(); i++)
00087     {
00088         DEBUG_INFO("Making new mesh remapper for image " << i << ".");
00089         //use the virtual method to get the right subclass for the MeshInfo
00090         meshes.push_back(this->ObtainMeshInfo(visualization_state->GetSrcImage(i), layout_mode_on));
00091     }
00092 }
00093 
00094 void MeshManager::RenderMesh(unsigned int image_number) const
00095 {
00096     meshes[image_number]->CallList();
00097 }
00098 
00099 unsigned int MeshManager::GetDisplayList(unsigned int image_number) const
00100 {
00101     return meshes[image_number]->display_list_number;
00102 }
00103 
00104 void MeshManager::SetLayoutMode(bool state)
00105 {
00106     if (layout_mode_on == state) return;
00107     layout_mode_on = state;
00108     /* All meshes must be recalculated, since the layout mode uses meshes that
00109      * do not resemble properly remapped images.
00110      */
00111     for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
00112         delete (*it);
00113     }
00114     meshes.clear();
00115 }
00116 
00117 void MeshManager::SetLayoutScale(double scale)
00118 {
00119     for(unsigned int i=0;i<meshes.size();i++)
00120         meshes[i]->SetScaleFactor(scale);
00121 };
00122 
00123 
00124 MeshManager::MeshInfo::MeshInfo(HuginBase::Panorama * m_pano_in,
00125                                 HuginBase::SrcPanoImage * image,
00126                                 VisualizationState * visualization_state_in,
00127                                 bool layout_mode_on_in)
00128     :   display_list_number(glGenLists(1)), // Find a free display list.
00129         image(*image),
00130         m_pano(m_pano_in),
00131         scale_factor(3.0),
00132         m_visualization_state(visualization_state_in),
00133         remap(layout_mode_on_in ? (MeshRemapper *) new LayoutRemapper(m_pano, &(this->image), m_visualization_state)
00134                                 : (MeshRemapper *) new ChoosyRemapper(m_pano, &(this->image), m_visualization_state)),
00135         layout_mode_on(layout_mode_on_in)
00136 {
00137 }
00138 
00139 MeshManager::MeshInfo::MeshInfo(const MeshInfo & source)
00140     // copy remap object and display list, instead of references.
00141     :   display_list_number(glGenLists(1)),
00142     image(source.image),
00143     m_pano(source.m_pano),
00144     scale_factor(3.0),
00145     m_visualization_state(source.m_visualization_state),
00146     remap(source.layout_mode_on ? (MeshRemapper *) new LayoutRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)
00147                                 : (MeshRemapper *) new ChoosyRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)),
00148     layout_mode_on(source.layout_mode_on)
00149 {
00150 }
00151 
00152 
00153 
00154 MeshManager::MeshInfo::~MeshInfo()
00155 {
00156     glDeleteLists(display_list_number, 1);
00157     delete remap;
00158 }
00159 
00160 void MeshManager::MeshInfo::Update()
00161 {
00162     if (layout_mode_on)
00163     {
00167         double scale = m_visualization_state->GetVisibleArea().width() /
00168                        sqrt((double) m_pano->getNrOfImages()) / scale_factor;
00169         MeshRemapper & remapper_ref = *remap;
00170         LayoutRemapper &r = dynamic_cast<LayoutRemapper &>(remapper_ref);
00171         r.setScale(scale);
00172     }
00173     this->CompileList();
00174 }
00175 
00176 MeshManager::MeshInfo::MeshCoords3D::MeshCoords3D(const MeshRemapper::Coords & coords)
00177 {
00178     for (int x = 0 ; x < 2 ; x++) {
00179         for (int y = 0 ; y < 2 ; y++) {
00180             tex_coords[x][y][0] = coords.tex_c[x][y][0];
00181             tex_coords[x][y][1] = coords.tex_c[x][y][1];
00182             vertex_coords[x][y][0] = coords.vertex_c[x][y][0];
00183             vertex_coords[x][y][1] = coords.vertex_c[x][y][1];
00184             vertex_coords[x][y][2] = 0;
00185         }
00186     }
00187 }
00188 
00189 void MeshManager::MeshInfo::SetScaleFactor(double scale)
00190 {
00191     scale_factor=scale;
00192     Update();
00193 };
00194 
00195 void MeshManager::MeshInfo::CallList() const
00196 {
00197     glCallList(display_list_number);
00198 }
00199 
00200 void MeshManager::MeshInfo::CompileList()
00201 {
00202     // build the display list from the coordinates generated by the remapper
00203 //    DEBUG_INFO("Preparing to compile a display list for overview for " << image_number
00204 //              << ".");
00205     DEBUG_ASSERT(remap);
00206     bool multiTexture=m_visualization_state->getViewState()->GetSupportMultiTexture();
00207     unsigned int number_of_faces = 0;
00208 
00209     DEBUG_DEBUG("mesh update compile pano");
00210 
00211     this->BeforeCompile();
00212 
00213     glNewList(display_list_number, GL_COMPILE);
00214 
00215         remap->UpdateAndResetIndex();
00216         DEBUG_INFO("Specifying faces in display list.");
00217 
00218         glPushMatrix();
00219 
00220         this->Transform();
00221         
00222         #ifndef WIREFRAME
00223         glBegin(GL_QUADS);
00224         #endif
00225             // get each face's coordinates from the remapper
00226             MeshRemapper::Coords coords;
00227             while (remap->GetNextFaceCoordinates(&coords))
00228             {
00229                 MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
00230 //                DEBUG_DEBUG("mesh update " << coords3d.vertex_coords[0][0][0] << " " << coords3d.vertex_coords[0][0][1] << " " << coords3d.vertex_coords[0][0][2]);
00231                 number_of_faces++;
00232                 // go in an anticlockwise direction
00233                 #ifdef WIREFRAME
00234                 glBegin(GL_LINE_LOOP);
00235                 #endif
00236                 if(multiTexture)
00237                 {
00238                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][0]);
00239                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][0]);
00240                 }
00241                 else
00242                     glTexCoord2dv(coords3d.tex_coords[0][0]);
00243                 glVertex3dv(coords3d.vertex_coords[0][0]);
00244                 if(multiTexture)
00245                 {
00246                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][1]);
00247                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][1]);
00248                 }
00249                 else
00250                     glTexCoord2dv(coords3d.tex_coords[0][1]);
00251                 glVertex3dv(coords3d.vertex_coords[0][1]);
00252                 if(multiTexture)
00253                 {
00254                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][1]);
00255                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][1]);
00256                 }
00257                 else
00258                     glTexCoord2dv(coords3d.tex_coords[1][1]);
00259                 glVertex3dv(coords3d.vertex_coords[1][1]);
00260                  if(multiTexture)
00261                 {
00262                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][0]);
00263                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][0]);
00264                 }
00265                 else
00266                    glTexCoord2dv(coords3d.tex_coords[1][0]);
00267                 glVertex3dv(coords3d.vertex_coords[1][0]);
00268                 #ifdef WIREFRAME
00269                 glEnd();
00270                 #endif
00271             }
00272         #ifndef WIREFRAME
00273         glEnd();
00274         #endif
00275 
00276         glPopMatrix();
00277 
00278     glEndList();
00279 
00280 
00281     this->AfterCompile();
00282 //    DEBUG_INFO("Prepared a display list for " << image_number << ", using "
00283 //              << number_of_faces << " face(s).");
00284     DEBUG_DEBUG("after compile mesh");
00285 }
00286 
00287 void MeshManager::PanosphereOverviewMeshInfo::Convert(double &x, double &y, double &z, double th, double ph, double r)
00288 {
00289     th /= 180.0;
00290     th *= M_PI;
00291     ph /= 180.0;
00292     ph *= M_PI;
00293 
00294     x = r * sin(th) * cos(ph);
00295     y = r * sin(ph);
00296     z = r * cos(th) * cos(ph);
00297 }
00298 
00299 void MeshManager::PanosphereOverviewMeshInfo::BeforeCompile()
00300 {
00301     yaw = image.getYaw();
00302     pitch = image.getPitch();
00303 
00304     image.setYaw(0);
00305     image.setPitch(0);
00306 }
00307 
00308 void MeshManager::PanosphereOverviewMeshInfo::Transform()
00309 {
00310 
00311     glRotated(yaw, 0,-1,0);
00312     glRotated(pitch, -1,0,0);
00313 
00314 }
00315 
00316 void MeshManager::PanosphereOverviewMeshInfo::AfterCompile()
00317 {
00318     image.setYaw(yaw);
00319     image.setPitch(pitch);
00320 }
00321 
00322 MeshManager::MeshInfo::Coord3D MeshManager::PanosphereOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D & coord, VisualizationState * state)
00323 {
00324     double width, height, hfov, vfov;
00325     HuginBase::PanoramaOptions * opts = state->GetOptions();
00326     width = opts->getWidth();
00327     height = opts->getHeight();
00328 
00329     hfov = 360;
00330     vfov = 180;
00331 
00332     MeshManager::MeshInfo::Coord3D res;
00333 
00334     double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
00335     double th, ph;
00336     th = ((coord.x / width) * hfov - hfov / 2.0);
00337     ph = ((coord.y / height) * vfov - vfov / 2.0);
00338 
00339     Convert(
00340         res.x,
00341         res.y,
00342         res.z,
00343         -th,-ph,r);
00344 
00345     return res;
00346 }
00347 
00348 MeshManager::MeshInfo::MeshCoords3D MeshManager::PanosphereOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00349 {
00350     double width, height, hfov, vfov;
00351     HuginBase::PanoramaOptions * opts = state->GetOptions();
00352     width = opts->getWidth();
00353     height = opts->getHeight();
00354 
00355     hfov = 360;
00356     vfov = 180;
00357 
00358     double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
00359 
00360     MeshCoords3D res;
00361     for (int x = 0 ; x < 2 ; x++) {
00362         for (int y = 0 ; y < 2 ; y++) {
00363 
00364         
00365             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00366             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00367 
00368             double th, ph;
00369             th = ((coords.vertex_c[x][y][0] / width) * hfov - hfov / 2.0);
00370             ph = ((coords.vertex_c[x][y][1] / height) * vfov - vfov / 2.0);
00371 
00372             Convert(
00373                 res.vertex_coords[x][y][0],
00374                 res.vertex_coords[x][y][1],
00375                 res.vertex_coords[x][y][2],
00376                 -th,-ph,r);
00377                 
00378 //            DEBUG_DEBUG("pano get " << res.vertex_coords[x][y][0] << " " << res.vertex_coords[x][y][1] << " " << res.vertex_coords[x][y][2]);
00379 //            DEBUG_DEBUG("pano get " << coords.vertex_c[x][y][0] << " " << coords.vertex_c[x][y][1]);
00380 
00381         }
00382     }
00383     return res;
00384 }
00385 
00386 
00387 const double MeshManager::PlaneOverviewMeshInfo::scale = 100;
00388 
00389 MeshManager::MeshInfo::Coord3D MeshManager::PlaneOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState * state)
00390 {
00391     double width, height;
00392     HuginBase::PanoramaOptions * opts = state->GetOptions();
00393     width = opts->getWidth();
00394     height = opts->getHeight();
00395 
00396     Coord3D res;
00397     res.x = (coord.x - width / 2.0) * scale / width;
00398     res.y = (coord.y - height / 2.0) * (-scale) / width;
00399     res.z = 0;
00400     return res;
00401 }
00402 
00403 MeshManager::MeshInfo::MeshCoords3D MeshManager::PlaneOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00404 {
00405     double width, height;
00406     HuginBase::PanoramaOptions * opts = state->GetOptions();
00407     width = opts->getWidth();
00408     height = opts->getHeight();
00409 
00410     MeshCoords3D res;
00411     for (int x = 0 ; x < 2 ; x++) {
00412         for (int y = 0 ; y < 2 ; y++) {
00413             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00414             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00415 
00416             res.vertex_coords[x][y][0] = (coords.vertex_c[x][y][0] - width / 2.0) * scale / width;
00417             res.vertex_coords[x][y][1] = (coords.vertex_c[x][y][1] - height / 2.0) * (-scale) / width;
00418             res.vertex_coords[x][y][2] = 0;
00419         }
00420     }
00421     return res;
00422 
00423 }
00424 
00425 MeshManager::MeshInfo * PanosphereOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00426 {
00427     return new MeshManager::PanosphereOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00428 }
00429 
00430 MeshManager::MeshInfo * PlaneOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00431 {
00432     return new MeshManager::PlaneOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00433 }
00434 
00435 MeshManager::MeshInfo * PreviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00436 {
00437     return new MeshManager::PreviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00438 }
00439 
00440 
00441 

Generated on 5 May 2016 for Hugintrunk by  doxygen 1.4.7