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(PT::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(PT::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             bool write = true;
00231             while (remap->GetNextFaceCoordinates(&coords))
00232             {
00233                 MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
00234 //                DEBUG_DEBUG("mesh update " << coords3d.vertex_coords[0][0][0] << " " << coords3d.vertex_coords[0][0][1] << " " << coords3d.vertex_coords[0][0][2]);
00235                 number_of_faces++;
00236                 // go in an anticlockwise direction
00237                 #ifdef WIREFRAME
00238                 glBegin(GL_LINE_LOOP);
00239                 #endif
00240                 if(multiTexture)
00241                 {
00242                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][0]);
00243                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][0]);
00244                 }
00245                 else
00246                     glTexCoord2dv(coords3d.tex_coords[0][0]);
00247                 glVertex3dv(coords3d.vertex_coords[0][0]);
00248                 if(multiTexture)
00249                 {
00250                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][1]);
00251                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][1]);
00252                 }
00253                 else
00254                     glTexCoord2dv(coords3d.tex_coords[0][1]);
00255                 glVertex3dv(coords3d.vertex_coords[0][1]);
00256                 if(multiTexture)
00257                 {
00258                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][1]);
00259                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][1]);
00260                 }
00261                 else
00262                     glTexCoord2dv(coords3d.tex_coords[1][1]);
00263                 glVertex3dv(coords3d.vertex_coords[1][1]);
00264                  if(multiTexture)
00265                 {
00266                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][0]);
00267                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][0]);
00268                 }
00269                 else
00270                    glTexCoord2dv(coords3d.tex_coords[1][0]);
00271                 glVertex3dv(coords3d.vertex_coords[1][0]);
00272                 #ifdef WIREFRAME
00273                 glEnd();
00274                 #endif
00275             }
00276         #ifndef WIREFRAME
00277         glEnd();
00278         #endif
00279 
00280         glPopMatrix();
00281 
00282     glEndList();
00283 
00284 
00285     this->AfterCompile();
00286 //    DEBUG_INFO("Prepared a display list for " << image_number << ", using "
00287 //              << number_of_faces << " face(s).");
00288     DEBUG_DEBUG("after compile mesh");
00289 }
00290 
00291 void MeshManager::PanosphereOverviewMeshInfo::Convert(double &x, double &y, double &z, double th, double ph, double r)
00292 {
00293     th /= 180.0;
00294     th *= M_PI;
00295     ph /= 180.0;
00296     ph *= M_PI;
00297 
00298     x = r * sin(th) * cos(ph);
00299     y = r * sin(ph);
00300     z = r * cos(th) * cos(ph);
00301 }
00302 
00303 void MeshManager::PanosphereOverviewMeshInfo::BeforeCompile()
00304 {
00305     yaw = image.getYaw();
00306     pitch = image.getPitch();
00307 
00308     image.setYaw(0);
00309     image.setPitch(0);
00310 }
00311 
00312 void MeshManager::PanosphereOverviewMeshInfo::Transform()
00313 {
00314 
00315     glRotated(yaw, 0,-1,0);
00316     glRotated(pitch, -1,0,0);
00317 
00318 }
00319 
00320 void MeshManager::PanosphereOverviewMeshInfo::AfterCompile()
00321 {
00322     image.setYaw(yaw);
00323     image.setPitch(pitch);
00324 }
00325 
00326 MeshManager::MeshInfo::Coord3D MeshManager::PanosphereOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D & coord, VisualizationState * state)
00327 {
00328     double width, height, hfov, vfov;
00329     HuginBase::PanoramaOptions * opts = state->GetOptions();
00330     width = opts->getWidth();
00331     height = opts->getHeight();
00332 
00333     hfov = 360;
00334     vfov = 180;
00335 
00336     MeshManager::MeshInfo::Coord3D res;
00337 
00338     double r = ((PanosphereOverviewVisualizationState*)state)->getSphereRadius();
00339     double th, ph;
00340     th = ((coord.x / width) * hfov - hfov / 2.0);
00341     ph = ((coord.y / height) * vfov - vfov / 2.0);
00342 
00343     Convert(
00344         res.x,
00345         res.y,
00346         res.z,
00347         -th,-ph,r);
00348 
00349     return res;
00350 }
00351 
00352 MeshManager::MeshInfo::MeshCoords3D MeshManager::PanosphereOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00353 {
00354     double width, height, hfov, vfov;
00355     HuginBase::PanoramaOptions * opts = state->GetOptions();
00356     width = opts->getWidth();
00357     height = opts->getHeight();
00358 
00359     hfov = 360;
00360     vfov = 180;
00361 
00362     double r = ((PanosphereOverviewVisualizationState*)state)->getSphereRadius();
00363 
00364     MeshCoords3D res;
00365     for (int x = 0 ; x < 2 ; x++) {
00366         for (int y = 0 ; y < 2 ; y++) {
00367 
00368         
00369             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00370             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00371 
00372             double th, ph;
00373             th = ((coords.vertex_c[x][y][0] / width) * hfov - hfov / 2.0);
00374             ph = ((coords.vertex_c[x][y][1] / height) * vfov - vfov / 2.0);
00375 
00376             Convert(
00377                 res.vertex_coords[x][y][0],
00378                 res.vertex_coords[x][y][1],
00379                 res.vertex_coords[x][y][2],
00380                 -th,-ph,r);
00381                 
00382 //            DEBUG_DEBUG("pano get " << res.vertex_coords[x][y][0] << " " << res.vertex_coords[x][y][1] << " " << res.vertex_coords[x][y][2]);
00383 //            DEBUG_DEBUG("pano get " << coords.vertex_c[x][y][0] << " " << coords.vertex_c[x][y][1]);
00384 
00385         }
00386     }
00387     return res;
00388 }
00389 
00390 
00391 const double MeshManager::PlaneOverviewMeshInfo::scale = 100;
00392 
00393 MeshManager::MeshInfo::Coord3D MeshManager::PlaneOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState * state)
00394 {
00395     double width, height;
00396     HuginBase::PanoramaOptions * opts = state->GetOptions();
00397     width = opts->getWidth();
00398     height = opts->getHeight();
00399 
00400     Coord3D res;
00401     res.x = (coord.x - width / 2.0) * scale / width;
00402     res.y = (coord.y - height / 2.0) * (-scale) / width;
00403     res.z = 0;
00404     return res;
00405 }
00406 
00407 MeshManager::MeshInfo::MeshCoords3D MeshManager::PlaneOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00408 {
00409     double width, height;
00410     HuginBase::PanoramaOptions * opts = state->GetOptions();
00411     width = opts->getWidth();
00412     height = opts->getHeight();
00413 
00414     MeshCoords3D res;
00415     for (int x = 0 ; x < 2 ; x++) {
00416         for (int y = 0 ; y < 2 ; y++) {
00417             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00418             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00419 
00420             res.vertex_coords[x][y][0] = (coords.vertex_c[x][y][0] - width / 2.0) * scale / width;
00421             res.vertex_coords[x][y][1] = (coords.vertex_c[x][y][1] - height / 2.0) * (-scale) / width;
00422             res.vertex_coords[x][y][2] = 0;
00423         }
00424     }
00425     return res;
00426 
00427 }
00428 
00429 MeshManager::MeshInfo * PanosphereOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00430 {
00431     return new MeshManager::PanosphereOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00432 }
00433 
00434 MeshManager::MeshInfo * PlaneOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00435 {
00436     return new MeshManager::PlaneOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00437 }
00438 
00439 MeshManager::MeshInfo * PreviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00440 {
00441     return new MeshManager::PreviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00442 }
00443 
00444 
00445 

Generated on 5 Dec 2014 for Hugintrunk by  doxygen 1.4.7