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 bool MeshManager::GetLayoutMode() const
00118 {
00119     return layout_mode_on;
00120 }
00121 
00122 void MeshManager::SetLayoutScale(double scale)
00123 {
00124     for(unsigned int i=0;i<meshes.size();i++)
00125         meshes[i]->SetScaleFactor(scale);
00126 };
00127 
00128 
00129 MeshManager::MeshInfo::MeshInfo(HuginBase::Panorama * m_pano_in,
00130                                 HuginBase::SrcPanoImage * image,
00131                                 VisualizationState * visualization_state_in,
00132                                 bool layout_mode_on_in)
00133     :   display_list_number(glGenLists(1)), // Find a free display list.
00134         image(*image),
00135         m_pano(m_pano_in),
00136         scale_factor(3.0),
00137         m_visualization_state(visualization_state_in),
00138         remap(layout_mode_on_in ? (MeshRemapper *) new LayoutRemapper(m_pano, &(this->image), m_visualization_state)
00139                                 : (MeshRemapper *) new ChoosyRemapper(m_pano, &(this->image), m_visualization_state)),
00140         layout_mode_on(layout_mode_on_in)
00141 {
00142 }
00143 
00144 MeshManager::MeshInfo::MeshInfo(const MeshInfo & source)
00145     // copy remap object and display list, instead of references.
00146     :   display_list_number(glGenLists(1)),
00147     image(source.image),
00148     m_pano(source.m_pano),
00149     scale_factor(3.0),
00150     m_visualization_state(source.m_visualization_state),
00151     remap(source.layout_mode_on ? (MeshRemapper *) new LayoutRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)
00152                                 : (MeshRemapper *) new ChoosyRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)),
00153     layout_mode_on(source.layout_mode_on)
00154 {
00155 }
00156 
00157 
00158 
00159 MeshManager::MeshInfo::~MeshInfo()
00160 {
00161     glDeleteLists(display_list_number, 1);
00162     delete remap;
00163 }
00164 
00165 void MeshManager::MeshInfo::Update()
00166 {
00167     if (layout_mode_on)
00168     {
00172         double scale = m_visualization_state->GetVisibleArea().width() /
00173                        sqrt((double) m_pano->getNrOfImages()) / scale_factor;
00174         MeshRemapper & remapper_ref = *remap;
00175         LayoutRemapper &r = dynamic_cast<LayoutRemapper &>(remapper_ref);
00176         r.setScale(scale);
00177     }
00178     this->CompileList();
00179 }
00180 
00181 MeshManager::MeshInfo::MeshCoords3D::MeshCoords3D(const MeshRemapper::Coords & coords)
00182 {
00183     for (int x = 0 ; x < 2 ; x++) {
00184         for (int y = 0 ; y < 2 ; y++) {
00185             tex_coords[x][y][0] = coords.tex_c[x][y][0];
00186             tex_coords[x][y][1] = coords.tex_c[x][y][1];
00187             vertex_coords[x][y][0] = coords.vertex_c[x][y][0];
00188             vertex_coords[x][y][1] = coords.vertex_c[x][y][1];
00189             vertex_coords[x][y][2] = 0;
00190         }
00191     }
00192 }
00193 
00194 void MeshManager::MeshInfo::SetScaleFactor(double scale)
00195 {
00196     scale_factor=scale;
00197     Update();
00198 };
00199 
00200 void MeshManager::MeshInfo::CallList() const
00201 {
00202     glCallList(display_list_number);
00203 }
00204 
00205 void MeshManager::MeshInfo::CompileList()
00206 {
00207     // build the display list from the coordinates generated by the remapper
00208 //    DEBUG_INFO("Preparing to compile a display list for overview for " << image_number
00209 //              << ".");
00210     DEBUG_ASSERT(remap);
00211     bool multiTexture=m_visualization_state->getViewState()->GetSupportMultiTexture();
00212     unsigned int number_of_faces = 0;
00213 
00214     DEBUG_DEBUG("mesh update compile pano");
00215 
00216     this->BeforeCompile();
00217 
00218     glNewList(display_list_number, GL_COMPILE);
00219 
00220         remap->UpdateAndResetIndex();
00221         DEBUG_INFO("Specifying faces in display list.");
00222 
00223         glPushMatrix();
00224 
00225         this->Transform();
00226         
00227         #ifndef WIREFRAME
00228         glBegin(GL_QUADS);
00229         #endif
00230             // get each face's coordinates from the remapper
00231             MeshRemapper::Coords coords;
00232             while (remap->GetNextFaceCoordinates(&coords))
00233             {
00234                 MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
00235 //                DEBUG_DEBUG("mesh update " << coords3d.vertex_coords[0][0][0] << " " << coords3d.vertex_coords[0][0][1] << " " << coords3d.vertex_coords[0][0][2]);
00236                 number_of_faces++;
00237                 // go in an anticlockwise direction
00238                 #ifdef WIREFRAME
00239                 glBegin(GL_LINE_LOOP);
00240                 #endif
00241                 if(multiTexture)
00242                 {
00243                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][0]);
00244                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][0]);
00245                 }
00246                 else
00247                     glTexCoord2dv(coords3d.tex_coords[0][0]);
00248                 glVertex3dv(coords3d.vertex_coords[0][0]);
00249                 if(multiTexture)
00250                 {
00251                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][1]);
00252                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][1]);
00253                 }
00254                 else
00255                     glTexCoord2dv(coords3d.tex_coords[0][1]);
00256                 glVertex3dv(coords3d.vertex_coords[0][1]);
00257                 if(multiTexture)
00258                 {
00259                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][1]);
00260                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][1]);
00261                 }
00262                 else
00263                     glTexCoord2dv(coords3d.tex_coords[1][1]);
00264                 glVertex3dv(coords3d.vertex_coords[1][1]);
00265                  if(multiTexture)
00266                 {
00267                     glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][0]);
00268                     glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][0]);
00269                 }
00270                 else
00271                    glTexCoord2dv(coords3d.tex_coords[1][0]);
00272                 glVertex3dv(coords3d.vertex_coords[1][0]);
00273                 #ifdef WIREFRAME
00274                 glEnd();
00275                 #endif
00276             }
00277         #ifndef WIREFRAME
00278         glEnd();
00279         #endif
00280 
00281         glPopMatrix();
00282 
00283     glEndList();
00284 
00285 
00286     this->AfterCompile();
00287 //    DEBUG_INFO("Prepared a display list for " << image_number << ", using "
00288 //              << number_of_faces << " face(s).");
00289     DEBUG_DEBUG("after compile mesh");
00290 }
00291 
00292 void MeshManager::PanosphereOverviewMeshInfo::Convert(double &x, double &y, double &z, double th, double ph, double r)
00293 {
00294     th /= 180.0;
00295     th *= M_PI;
00296     ph /= 180.0;
00297     ph *= M_PI;
00298 
00299     x = r * sin(th) * cos(ph);
00300     y = r * sin(ph);
00301     z = r * cos(th) * cos(ph);
00302 }
00303 
00304 void MeshManager::PanosphereOverviewMeshInfo::BeforeCompile()
00305 {
00306     yaw = image.getYaw();
00307     pitch = image.getPitch();
00308 
00309     image.setYaw(0);
00310     image.setPitch(0);
00311 }
00312 
00313 void MeshManager::PanosphereOverviewMeshInfo::Transform()
00314 {
00315 
00316     glRotated(yaw, 0,-1,0);
00317     glRotated(pitch, -1,0,0);
00318 
00319 }
00320 
00321 void MeshManager::PanosphereOverviewMeshInfo::AfterCompile()
00322 {
00323     image.setYaw(yaw);
00324     image.setPitch(pitch);
00325 }
00326 
00327 MeshManager::MeshInfo::Coord3D MeshManager::PanosphereOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D & coord, VisualizationState * state)
00328 {
00329     double width, height, hfov, vfov;
00330     HuginBase::PanoramaOptions * opts = state->GetOptions();
00331     width = opts->getWidth();
00332     height = opts->getHeight();
00333 
00334     hfov = 360;
00335     vfov = 180;
00336 
00337     MeshManager::MeshInfo::Coord3D res;
00338 
00339     double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
00340     double th, ph;
00341     th = ((coord.x / width) * hfov - hfov / 2.0);
00342     ph = ((coord.y / height) * vfov - vfov / 2.0);
00343 
00344     Convert(
00345         res.x,
00346         res.y,
00347         res.z,
00348         -th,-ph,r);
00349 
00350     return res;
00351 }
00352 
00353 MeshManager::MeshInfo::MeshCoords3D MeshManager::PanosphereOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00354 {
00355     double width, height, hfov, vfov;
00356     HuginBase::PanoramaOptions * opts = state->GetOptions();
00357     width = opts->getWidth();
00358     height = opts->getHeight();
00359 
00360     hfov = 360;
00361     vfov = 180;
00362 
00363     double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
00364 
00365     MeshCoords3D res;
00366     for (int x = 0 ; x < 2 ; x++) {
00367         for (int y = 0 ; y < 2 ; y++) {
00368 
00369         
00370             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00371             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00372 
00373             double th, ph;
00374             th = ((coords.vertex_c[x][y][0] / width) * hfov - hfov / 2.0);
00375             ph = ((coords.vertex_c[x][y][1] / height) * vfov - vfov / 2.0);
00376 
00377             Convert(
00378                 res.vertex_coords[x][y][0],
00379                 res.vertex_coords[x][y][1],
00380                 res.vertex_coords[x][y][2],
00381                 -th,-ph,r);
00382                 
00383 //            DEBUG_DEBUG("pano get " << res.vertex_coords[x][y][0] << " " << res.vertex_coords[x][y][1] << " " << res.vertex_coords[x][y][2]);
00384 //            DEBUG_DEBUG("pano get " << coords.vertex_c[x][y][0] << " " << coords.vertex_c[x][y][1]);
00385 
00386         }
00387     }
00388     return res;
00389 }
00390 
00391 
00392 const double MeshManager::PlaneOverviewMeshInfo::scale = 100;
00393 
00394 MeshManager::MeshInfo::Coord3D MeshManager::PlaneOverviewMeshInfo::GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState * state)
00395 {
00396     double width, height;
00397     HuginBase::PanoramaOptions * opts = state->GetOptions();
00398     width = opts->getWidth();
00399     height = opts->getHeight();
00400 
00401     Coord3D res;
00402     res.x = (coord.x - width / 2.0) * scale / width;
00403     res.y = (coord.y - height / 2.0) * (-scale) / width;
00404     res.z = 0;
00405     return res;
00406 }
00407 
00408 MeshManager::MeshInfo::MeshCoords3D MeshManager::PlaneOverviewMeshInfo::GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState * state)
00409 {
00410     double width, height;
00411     HuginBase::PanoramaOptions * opts = state->GetOptions();
00412     width = opts->getWidth();
00413     height = opts->getHeight();
00414 
00415     MeshCoords3D res;
00416     for (int x = 0 ; x < 2 ; x++) {
00417         for (int y = 0 ; y < 2 ; y++) {
00418             res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
00419             res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
00420 
00421             res.vertex_coords[x][y][0] = (coords.vertex_c[x][y][0] - width / 2.0) * scale / width;
00422             res.vertex_coords[x][y][1] = (coords.vertex_c[x][y][1] - height / 2.0) * (-scale) / width;
00423             res.vertex_coords[x][y][2] = 0;
00424         }
00425     }
00426     return res;
00427 
00428 }
00429 
00430 MeshManager::MeshInfo * PanosphereOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00431 {
00432     return new MeshManager::PanosphereOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00433 }
00434 
00435 MeshManager::MeshInfo * PlaneOverviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00436 {
00437     return new MeshManager::PlaneOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00438 }
00439 
00440 MeshManager::MeshInfo * PreviewMeshManager::ObtainMeshInfo(HuginBase::SrcPanoImage * src, bool layout_mode_on)
00441 {
00442     return new MeshManager::PreviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
00443 }
00444 
00445 
00446 

Generated on 7 Dec 2016 for Hugintrunk by  doxygen 1.4.7