00001
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
00049
00050
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
00073 while (meshes.size() > m_pano->getNrOfImages())
00074 {
00075 delete (meshes[meshes.size()-1]);
00076 meshes.pop_back();
00077 }
00078
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
00089 for (unsigned int i = old_size; i < m_pano->getNrOfImages(); i++)
00090 {
00091 DEBUG_INFO("Making new mesh remapper for image " << i << ".");
00092
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
00112
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)),
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
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
00206
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
00229 MeshRemapper::Coords coords;
00230 bool write = true;
00231 while (remap->GetNextFaceCoordinates(&coords))
00232 {
00233 MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
00234
00235 number_of_faces++;
00236
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
00287
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
00383
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