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

Generated on 29 Jul 2015 for Hugintrunk by  doxygen 1.4.7