Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MeshManager.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
23 #include <wx/wx.h>
24 #include <wx/platform.h>
25 
26 #ifdef __WXMSW__
27 #include <vigra/windows.h>
28 #endif
29 
30 #include "hugin_config.h"
31 #if defined HAVE_EPOXY && HAVE_EPOXY
32 #include <epoxy/gl.h>
33 #else
34 #include <GL/glew.h>
35 #ifdef __WXMAC__
36 #include <OpenGL/gl.h>
37 #else
38 #include <GL/gl.h>
39 #endif
40 #endif
41 
42 #include "panoinc.h"
43 #include "ViewState.h"
44 #include "MeshManager.h"
45 #include "ChoosyRemapper.h"
46 #include "LayoutRemapper.h"
47 #include <iostream>
48 
49 
50 // If we want to draw the outline of each face instead of shading it normally,
51 // uncomment this. Wireframe mode is for testing mesh quality.
52 // #define WIREFRAME
53 
55 
57  : m_pano(pano),
58  visualization_state(visualization_state),
59  layout_mode_on(false)
60 {
61 }
62 
64 {
65  for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
66  delete (*it);
67  }
68  meshes.clear();
69 }
70 
72 {
73  unsigned int old_size = meshes.size();
74  // Resize to fit if images were removed
75  while (meshes.size() > m_pano->getNrOfImages())
76  {
77  delete (meshes[meshes.size()-1]);
78  meshes.pop_back();
79  }
80  // check each existing image individualy.
81  for (unsigned int i = 0; i < meshes.size(); i++)
82  {
84  {
85  DEBUG_DEBUG("Update mesh for " << i);
86  meshes[i]->SetSrcImage(visualization_state->GetSrcImage(i));
87  meshes[i]->Update();
88  }
89  }
90  // add any new images.
91  for (unsigned int i = old_size; i < m_pano->getNrOfImages(); i++)
92  {
93  DEBUG_INFO("Making new mesh remapper for image " << i << ".");
94  //use the virtual method to get the right subclass for the MeshInfo
96  }
97 }
98 
99 void MeshManager::RenderMesh(unsigned int image_number) const
100 {
101  meshes[image_number]->CallList();
102 }
103 
104 unsigned int MeshManager::GetDisplayList(unsigned int image_number) const
105 {
106  return meshes[image_number]->display_list_number;
107 }
108 
110 {
111  if (layout_mode_on == state) return;
112  layout_mode_on = state;
113  /* All meshes must be recalculated, since the layout mode uses meshes that
114  * do not resemble properly remapped images.
115  */
116  for (std::vector<MeshInfo*>::iterator it = meshes.begin() ; it != meshes.end() ; ++it) {
117  delete (*it);
118  }
119  meshes.clear();
120 }
121 
123 {
124  return layout_mode_on;
125 }
126 
127 void MeshManager::SetLayoutScale(double scale)
128 {
129  for(unsigned int i=0;i<meshes.size();i++)
130  meshes[i]->SetScaleFactor(scale);
131 };
132 
133 
135  HuginBase::SrcPanoImage * image,
136  VisualizationState * visualization_state_in,
137  bool layout_mode_on_in)
138  : display_list_number(glGenLists(1)), // Find a free display list.
139  image(*image),
140  m_pano(m_pano_in),
141  scale_factor(3.0),
142  m_visualization_state(visualization_state_in),
143  remap(layout_mode_on_in ? (MeshRemapper *) new LayoutRemapper(m_pano, &(this->image), m_visualization_state)
144  : (MeshRemapper *) new ChoosyRemapper(m_pano, &(this->image), m_visualization_state)),
145  layout_mode_on(layout_mode_on_in)
146 {
147 }
148 
150  // copy remap object and display list, instead of references.
151  : display_list_number(glGenLists(1)),
152  image(source.image),
153  m_pano(source.m_pano),
154  scale_factor(3.0),
155  m_visualization_state(source.m_visualization_state),
156  remap(source.layout_mode_on ? (MeshRemapper *) new LayoutRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)
157  : (MeshRemapper *) new ChoosyRemapper(source.m_pano, (HuginBase::SrcPanoImage*) &(source.image), source.m_visualization_state)),
159 {
160 }
161 
162 
163 
165 {
166  glDeleteLists(display_list_number, 1);
167  delete remap;
168 }
169 
171 {
172  if (layout_mode_on)
173  {
177  double scale = m_visualization_state->GetVisibleArea().width() /
178  sqrt((double) m_pano->getNrOfImages()) / scale_factor;
179  MeshRemapper & remapper_ref = *remap;
180  LayoutRemapper &r = dynamic_cast<LayoutRemapper &>(remapper_ref);
181  r.setScale(scale);
182  }
183  this->CompileList();
184 }
185 
187 {
188  for (int x = 0 ; x < 2 ; x++) {
189  for (int y = 0 ; y < 2 ; y++) {
190  tex_coords[x][y][0] = coords.tex_c[x][y][0];
191  tex_coords[x][y][1] = coords.tex_c[x][y][1];
192  vertex_coords[x][y][0] = coords.vertex_c[x][y][0];
193  vertex_coords[x][y][1] = coords.vertex_c[x][y][1];
194  vertex_coords[x][y][2] = 0;
195  }
196  }
197 }
198 
200 {
201  scale_factor=scale;
202  Update();
203 };
204 
206 {
207  glCallList(display_list_number);
208 }
209 
211 {
212  // build the display list from the coordinates generated by the remapper
213 // DEBUG_INFO("Preparing to compile a display list for overview for " << image_number
214 // << ".");
215  DEBUG_ASSERT(remap);
216  bool multiTexture=m_visualization_state->getViewState()->GetSupportMultiTexture();
217  unsigned int number_of_faces = 0;
218 
219  DEBUG_DEBUG("mesh update compile pano");
220 
221  this->BeforeCompile();
222 
223  glNewList(display_list_number, GL_COMPILE);
224 
225  remap->UpdateAndResetIndex();
226  DEBUG_INFO("Specifying faces in display list.");
227 
228  glPushMatrix();
229 
230  this->Transform();
231 
232  #ifndef WIREFRAME
233  glBegin(GL_QUADS);
234  #endif
235  // get each face's coordinates from the remapper
236  MeshRemapper::Coords coords;
237  while (remap->GetNextFaceCoordinates(&coords))
238  {
239  MeshCoords3D coords3d = m_visualization_state->GetMeshManager()->GetMeshCoords3D(coords);
240 // DEBUG_DEBUG("mesh update " << coords3d.vertex_coords[0][0][0] << " " << coords3d.vertex_coords[0][0][1] << " " << coords3d.vertex_coords[0][0][2]);
241  number_of_faces++;
242  // go in an anticlockwise direction
243  #ifdef WIREFRAME
244  glBegin(GL_LINE_LOOP);
245  #endif
246  if(multiTexture)
247  {
248  glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][0]);
249  glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][0]);
250  }
251  else
252  glTexCoord2dv(coords3d.tex_coords[0][0]);
253  glVertex3dv(coords3d.vertex_coords[0][0]);
254  if(multiTexture)
255  {
256  glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[0][1]);
257  glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[0][1]);
258  }
259  else
260  glTexCoord2dv(coords3d.tex_coords[0][1]);
261  glVertex3dv(coords3d.vertex_coords[0][1]);
262  if(multiTexture)
263  {
264  glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][1]);
265  glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][1]);
266  }
267  else
268  glTexCoord2dv(coords3d.tex_coords[1][1]);
269  glVertex3dv(coords3d.vertex_coords[1][1]);
270  if(multiTexture)
271  {
272  glMultiTexCoord2dv(GL_TEXTURE0,coords3d.tex_coords[1][0]);
273  glMultiTexCoord2dv(GL_TEXTURE1,coords3d.tex_coords[1][0]);
274  }
275  else
276  glTexCoord2dv(coords3d.tex_coords[1][0]);
277  glVertex3dv(coords3d.vertex_coords[1][0]);
278  #ifdef WIREFRAME
279  glEnd();
280  #endif
281  }
282  #ifndef WIREFRAME
283  glEnd();
284  #endif
285 
286  glPopMatrix();
287 
288  glEndList();
289 
290 
291  this->AfterCompile();
292 // DEBUG_INFO("Prepared a display list for " << image_number << ", using "
293 // << number_of_faces << " face(s).");
294  DEBUG_DEBUG("after compile mesh");
295 }
296 
297 void MeshManager::PanosphereOverviewMeshInfo::Convert(double &x, double &y, double &z, double th, double ph, double r)
298 {
299  th /= 180.0;
300  th *= M_PI;
301  ph /= 180.0;
302  ph *= M_PI;
303 
304  x = r * sin(th) * cos(ph);
305  y = r * sin(ph);
306  z = r * cos(th) * cos(ph);
307 }
308 
310 {
311  yaw = image.getYaw();
312  pitch = image.getPitch();
313 
314  image.setYaw(0);
315  image.setPitch(0);
316 }
317 
319 {
320 
321  glRotated(yaw, 0,-1,0);
322  glRotated(pitch, -1,0,0);
323 
324 }
325 
327 {
328  image.setYaw(yaw);
329  image.setPitch(pitch);
330 }
331 
333 {
334  double width, height, hfov, vfov;
335  HuginBase::PanoramaOptions * opts = state->GetOptions();
336  width = opts->getWidth();
337  height = opts->getHeight();
338 
339  hfov = 360;
340  vfov = 180;
341 
343 
344  double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
345  double th, ph;
346  th = ((coord.x / width) * hfov - hfov / 2.0);
347  ph = ((coord.y / height) * vfov - vfov / 2.0);
348 
349  Convert(
350  res.x,
351  res.y,
352  res.z,
353  -th,-ph,r);
354 
355  return res;
356 }
357 
359 {
360  double width, height, hfov, vfov;
361  HuginBase::PanoramaOptions * opts = state->GetOptions();
362  width = opts->getWidth();
363  height = opts->getHeight();
364 
365  hfov = 360;
366  vfov = 180;
367 
368  double r = static_cast<PanosphereOverviewVisualizationState*>(state)->getSphereRadius();
369 
370  MeshCoords3D res;
371  for (int x = 0 ; x < 2 ; x++) {
372  for (int y = 0 ; y < 2 ; y++) {
373 
374 
375  res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
376  res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
377 
378  double th, ph;
379  th = ((coords.vertex_c[x][y][0] / width) * hfov - hfov / 2.0);
380  ph = ((coords.vertex_c[x][y][1] / height) * vfov - vfov / 2.0);
381 
382  Convert(
383  res.vertex_coords[x][y][0],
384  res.vertex_coords[x][y][1],
385  res.vertex_coords[x][y][2],
386  -th,-ph,r);
387 
388 // DEBUG_DEBUG("pano get " << res.vertex_coords[x][y][0] << " " << res.vertex_coords[x][y][1] << " " << res.vertex_coords[x][y][2]);
389 // DEBUG_DEBUG("pano get " << coords.vertex_c[x][y][0] << " " << coords.vertex_c[x][y][1]);
390 
391  }
392  }
393  return res;
394 }
395 
396 
398 
400 {
401  double width, height;
402  HuginBase::PanoramaOptions * opts = state->GetOptions();
403  width = opts->getWidth();
404  height = opts->getHeight();
405 
406  Coord3D res;
407  res.x = (coord.x - width / 2.0) * scale / width;
408  res.y = (coord.y - height / 2.0) * (-scale) / width;
409  res.z = 0;
410  return res;
411 }
412 
414 {
415  double width, height;
416  HuginBase::PanoramaOptions * opts = state->GetOptions();
417  width = opts->getWidth();
418  height = opts->getHeight();
419 
420  MeshCoords3D res;
421  for (int x = 0 ; x < 2 ; x++) {
422  for (int y = 0 ; y < 2 ; y++) {
423  res.tex_coords[x][y][0] = coords.tex_c[x][y][0];
424  res.tex_coords[x][y][1] = coords.tex_c[x][y][1];
425 
426  res.vertex_coords[x][y][0] = (coords.vertex_c[x][y][0] - width / 2.0) * scale / width;
427  res.vertex_coords[x][y][1] = (coords.vertex_c[x][y][1] - height / 2.0) * (-scale) / width;
428  res.vertex_coords[x][y][2] = 0;
429  }
430  }
431  return res;
432 
433 }
434 
436 {
437  return new MeshManager::PanosphereOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
438 }
439 
441 {
442  return new MeshManager::PlaneOverviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
443 }
444 
446 {
447  return new MeshManager::PreviewMeshInfo(m_pano, src, visualization_state, layout_mode_on);
448 }
449 
450 
451 
#define DEBUG_INFO(msg)
Definition: utils.h:69
a subclass for the panosphere it converts coordinates obtained from an equirectangular projection to ...
Definition: MeshManager.h:154
implementation of huginApp Class
An abstract base class for objects that calculate an approximate remap specified by quadrilatrials...
Definition: MeshRemapper.h:43
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
void CompileList()
Use the remapper to create the display list.
MeshInfo(HuginBase::Panorama *m_pano, HuginBase::SrcPanoImage *image, VisualizationState *visualization_state, bool layout_mode_on)
Constructor: Creates the mesh for a given image of a panorama.
subclass for the plane overview mode.
Definition: MeshManager.h:193
void setScale(double scale)
Set the size to draw the images.
A class for exchanging pointers to coordinates.
Definition: MeshRemapper.h:60
unsigned int getHeight() const
get panorama height
void SetLayoutScale(double scale)
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
include file for the hugin project
double(* tex_c)[2][2]
The coordinate in the source image ranging from 0 to 1.
Definition: MeshRemapper.h:64
static MeshCoords3D GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState *state)
bool GetLayoutMode() const
return if layout mode is active
Draw undistored images, but with the correct centre position.
virtual ~MeshManager()
Definition: MeshManager.cpp:63
Model for a panorama.
Definition: Panorama.h:152
bool layout_mode_on
Definition: MeshManager.h:227
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
HuginBase::Panorama * m_pano
Definition: MeshManager.h:222
virtual HuginBase::SrcPanoImage * GetSrcImage(unsigned int image_nr)
Definition: ViewState.cpp:478
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
std::vector< MeshInfo * > meshes
Definition: MeshManager.h:226
void Update()
Recreate the mesh when the image or panorama it represents changes.
static void Convert(double &x, double &y, double &z, double th, double ph, double r)
convert from spherical to cartesian coordinates
VisualizationState * visualization_state
Definition: MeshManager.h:223
unsigned int getWidth() const
bool RequireRecalculateMesh(unsigned int image_nr)
Definition: ViewState.cpp:420
Handles the remapper and a display list for a specific image.
Definition: MeshManager.h:64
virtual MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)=0
MeshInfo * ObtainMeshInfo(HuginBase::SrcPanoImage *, bool layout_mode_on)
static const double scale_diff
scale factor to be used for the layout mode TODO: test this for more scenarios
Definition: MeshManager.h:178
static MeshCoords3D GetMeshCoords3D(MeshRemapper::Coords &coords, VisualizationState *state)
virtual HuginBase::PanoramaOptions * GetOptions()
Definition: ViewState.cpp:468
void RenderMesh(unsigned int image_number) const
Definition: MeshManager.cpp:99
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
a class to keep data of a single rectangle with texture coordinates
Definition: MeshManager.h:104
Define a remapper to use in the layout mode.
A ChoosyRemapper combines the other MeshRemappers and picks which one it deems is best suited for eac...
void SetLayoutMode(bool state)
Turn layout mode on or off.
void SetScaleFactor(double scale)
subclass of MeshInfo for the preview It actually does nothing in addition to the base class ...
Definition: MeshManager.h:134
double(* vertex_c)[2][2]
The coordinate in the panorama, in its pixel space.
Definition: MeshRemapper.h:66
All variables of a source image.
Definition: SrcPanoImage.h:194
static Coord3D GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState *state)
Panorama image options.
#define M_PI
Definition: GaborFilter.cpp:34
void CallList() const
Draw the mesh.
static Coord3D GetCoord3D(hugin_utils::FDiff2D &coord, VisualizationState *state)
a class to handle a 3D point
Definition: MeshManager.h:93
MeshManager(HuginBase::Panorama *pano, VisualizationState *visualization_state)
Definition: MeshManager.cpp:56
unsigned int GetDisplayList(unsigned int image_number) const
void CheckUpdate()
Definition: MeshManager.cpp:71