00001
00002
00024 #ifdef __WXMAC__
00025 #include "panoinc_WX.h"
00026 #include "panoinc.h"
00027 #endif
00028
00029 #include "ViewState.h"
00030 #include "MeshManager.h"
00031
00032
00033
00034 ViewState::ViewState(PT::Panorama *pano, bool supportMultiTexture)
00035 {
00036
00037
00038 m_pano = pano;
00039 m_multiTexture=supportMultiTexture;
00040 m_pano->addObserver(this);
00041
00042 dirty_image_sizes = true;
00043 images_removed = true;
00044 number_of_images = m_pano->getNrOfImages();
00045 for (unsigned int img = 0; img < number_of_images; img++)
00046 {
00047 img_states[img] = m_pano->getSrcImage(img);
00048 dirty_mask[img].val = false;
00049 }
00050 opts = m_pano->getOptions();
00051 projection_info = new OutputProjectionInfo(&opts);
00052
00053 m_tex_manager = new TextureManager(m_pano, this);
00054 }
00055
00056 ViewState::~ViewState()
00057 {
00058 m_pano->removeObserver(this);
00059 delete projection_info;
00060 delete m_tex_manager;
00061 }
00062
00063
00064 void ViewState::panoramaChanged(HuginBase::PanoramaData &pano)
00065 {
00066
00067 bool require_draw=false;
00068
00069
00070 HuginBase::PanoramaOptions new_opts = m_pano->getOptions();
00071 SetOptions(&new_opts);
00072 unsigned int imgs = m_pano->getNrOfImages();
00073 for (unsigned int img = 0; img < imgs; img++)
00074 {
00075 HuginBase::SrcPanoImage new_image = m_pano->getSrcImage(img);
00076 SetSrcImage(img, &new_image);
00077
00078 bool new_active = m_pano->getImage(img).getActive();
00079 if (new_active != active[img])
00080 {
00081 require_draw = true;
00082 active[img] = new_active;
00083 }
00084 }
00085
00086 if (imgs < number_of_images)
00087 {
00088
00089 dirty_image_sizes = true;
00090 require_draw = true;
00091 images_removed = true;
00092 } else if (imgs > number_of_images)
00093 {
00094
00095 dirty_image_sizes = true;
00096 require_draw = true;
00097
00098
00099 }
00100 number_of_images = imgs;
00101
00102 if (require_draw) {
00103
00104 for (std::map<VisualizationState*,bool>::iterator it = vis_states.begin() ; it != vis_states.end() ; it++) {
00105 DEBUG_DEBUG("PanoChanged - iterator before");
00106 if (it->second) {
00107 DEBUG_DEBUG("PanoChanged - iterator after");
00108 it->first->Redraw();
00109 }
00110 }
00111 }
00112
00113 }
00114
00115 void ViewState::panoramaImagesChanged(HuginBase::PanoramaData&,
00116 const HuginBase::UIntSet&)
00117 {
00118
00119 }
00120
00121 void ViewState::SetOptions(const HuginBase::PanoramaOptions *new_opts)
00122 {
00123
00124 bool dirty_projection = false;
00125
00126 for (std::map<VisualizationState*,bool>::iterator it = vis_states.begin() ; it != vis_states.end() ; it++) {
00127
00128 if (!(it->second)) continue;
00129
00130
00131 if ( new_opts->getSize() != opts.getSize()
00132 || new_opts->getProjection() != opts.getProjection()
00133 || new_opts->getProjectionParameters() != opts.getProjectionParameters()
00134 || new_opts->getHFOV() != opts.getHFOV()
00135 || new_opts->getVFOV() != opts.getVFOV()
00136 )
00137 {
00138
00139 unsigned int imgs = m_pano->getNrOfImages();
00140 for (unsigned int img = 0; img < imgs; img++)
00141 {
00142 it->first->SetDirtyMesh(img);
00143 }
00144
00145 dirty_projection = true;
00146 it->first->SetDirtyViewport();
00147 it->first->ForceRequireRedraw();
00148 }
00149 if ( new_opts->outputExposureValue != opts.outputExposureValue)
00150 {
00151
00152 it->first->SetDirtyViewport();
00153 dirty_photometrics = true;
00154 }
00155 if ( new_opts->getROI() != opts.getROI()
00156 )
00157 {
00158
00159 it->first->ForceRequireRedraw();
00160 }
00161
00162 it->first->SetOptions(new_opts);
00163
00164 }
00165
00166 opts = *new_opts;
00167 if (dirty_projection)
00168 {
00169
00170 delete projection_info;
00171 projection_info = 0;
00172 projection_info = new OutputProjectionInfo(&opts);
00173 }
00174 }
00175
00176 void ViewState::SetSrcImage(unsigned int image_nr, HuginBase::SrcPanoImage *new_img)
00177 {
00178 bool dirty_mesh = false;
00179 bool dirty_draw = false;
00180
00181 if (number_of_images <= image_nr)
00182 {
00183
00184 dirty_mesh = true;
00185 dirty_image_sizes = true;
00186 dirty_draw = true;
00187 } else {
00188
00189 HuginBase::SrcPanoImage *img = &img_states[image_nr];
00190
00191 if (new_img->getFilename() != img->getFilename())
00192 {
00193 images_removed = true;
00194
00195
00196 }
00197
00198 if ( new_img->getRoll() != img->getRoll()
00199 || new_img->getPitch() != img->getPitch()
00200 || new_img->getYaw() != img->getYaw()
00201 || new_img->getX() != img->getX()
00202 || new_img->getY() != img->getY()
00203 || new_img->getZ() != img->getZ()
00204 || new_img->getHFOV() != img->getHFOV()
00205 || new_img->getProjection() != img->getProjection()
00206 || new_img->getShear() != img->getShear()
00207 || new_img->getRadialDistortionCenterShift()
00208 == img->getRadialDistortionCenterShift()
00209 || new_img->getRadialDistortion() != img->getRadialDistortion()
00210 || new_img->getCropRect() != img->getCropRect()
00211 )
00212 {
00213 dirty_mesh = true;
00214 dirty_draw = true;
00215
00216
00217 if (new_img->getHFOV() != img->getHFOV())
00218 {
00219 dirty_image_sizes = true;
00220 }
00221 }
00222
00223 if ( new_img->getVigCorrMode() != img->getVigCorrMode()
00224 || new_img->getRadialVigCorrCoeff() != img->getRadialVigCorrCoeff()
00225 || new_img->getRadialVigCorrCenterShift() !=
00226 img->getRadialVigCorrCenterShift()
00227 || new_img->getExposureValue() != img->getExposureValue()
00228 || new_img->getGamma() != img->getGamma()
00229 || new_img->getWhiteBalanceRed() != img->getWhiteBalanceRed()
00230 || new_img->getWhiteBalanceBlue() != img->getWhiteBalanceBlue()
00231 || new_img->getResponseType() != img->getResponseType()
00232 )
00233 {
00234
00235
00236
00237
00238
00239 dirty_draw = true;
00240 }
00241
00242 if(new_img->getActiveMasks() != img->getActiveMasks())
00243 {
00244 dirty_mask[image_nr].val = true;
00245 dirty_draw=true;
00246 };
00247 }
00248
00249 img_states[image_nr] = *new_img;
00250
00251
00252 for (std::map<VisualizationState*,bool>::iterator it = vis_states.begin() ; it != vis_states.end() ; it++) {
00253 if (!(it->second)) continue;
00254 if (dirty_draw) it->first->ForceRequireRedraw();
00255 if (dirty_mesh) it->first->SetDirtyMesh(image_nr);
00256 it->first->SetSrcImage(image_nr, new_img);
00257 }
00258
00259 }
00260
00261 void ViewState::ForceRequireRedraw()
00262 {
00263
00264
00265
00266 for (std::map<VisualizationState*,bool>::iterator it = vis_states.begin() ; it != vis_states.end() ; it++) {
00267 if (!(it->second)) continue;
00268 it->first->ForceRequireRedraw();
00269 }
00270 }
00271
00272
00273 HuginBase::PanoramaOptions *ViewState::GetOptions()
00274 {
00275 return &opts;
00276 }
00277
00278 OutputProjectionInfo *ViewState::GetProjectionInfo()
00279 {
00280 return projection_info;
00281 }
00282
00283 HuginBase::SrcPanoImage *ViewState::GetSrcImage(unsigned int image_nr)
00284 {
00285 return &img_states[image_nr];
00286 }
00287
00288
00289 bool ViewState::RequireRecalculateImageSizes()
00290 {
00291 return dirty_image_sizes;
00292 }
00293
00294 bool ViewState::RequireRecalculatePhotometric()
00295 {
00296 return dirty_photometrics;
00297 }
00298
00299 bool ViewState::ImagesRemoved()
00300 {
00301 return images_removed;
00302 }
00303
00304 bool ViewState::RequireRecalculateMasks(unsigned int image_nr)
00305 {
00306 if (number_of_images > image_nr)
00307 {
00308 return dirty_mask[image_nr].val;
00309 }
00310 return false;
00311 }
00312
00313
00314 void ViewState::FinishedDraw()
00315 {
00316
00317 number_of_images = m_pano->getNrOfImages();
00318 img_states.clear();
00319 active.clear();
00320 for (unsigned int img = 0; img < number_of_images; img++)
00321 {
00322 img_states[img] = m_pano->getSrcImage(img);
00323 active[img] = m_pano->getImage(img).getActive();
00324 }
00325 opts = m_pano->getOptions();
00326
00327 Clean();
00328 }
00329
00330 void ViewState::Clean()
00331 {
00332 dirty_image_sizes = false;
00333 images_removed = false;
00334 dirty_photometrics = false;
00335 dirty_mask.clear();
00336 }
00337
00338 void ViewState::DoUpdates()
00339 {
00340 DEBUG_DEBUG("VIEW STATE DO UPDATES");
00341 m_tex_manager->CheckUpdate();
00342 DEBUG_DEBUG("VIEW STATE END DO UPDATES");
00343 }
00344
00345 void ViewState::Redraw()
00346 {
00347
00348 for (std::map<VisualizationState*,bool>::iterator it = vis_states.begin() ; it != vis_states.end() ; it++) {
00349
00350 if (!(it->second)) continue;
00351
00352 it->first->Redraw();
00353
00354 }
00355
00356
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 VisualizationState::~VisualizationState()
00367 {
00368 m_view_state->vis_states[this] = false;
00369 delete m_mesh_manager;
00370 }
00371
00372
00373 float VisualizationState::GetScale()
00374 {
00375 return scale;
00376 }
00377
00378 void VisualizationState::SetScale(float scale_in)
00379 {
00380 scale = scale_in;
00381
00382
00383
00384 if (genscale == 0.0)
00385 {
00386
00387
00388 genscale = scale;
00389 } else {
00390 double difference = scale > genscale ?
00391 scale / genscale : genscale / scale;
00392 if (difference > 1.25)
00393 {
00394 genscale = scale;
00395 unsigned int number_of_images = m_pano->getNrOfImages();
00396 for (unsigned int img = 0; img < number_of_images; img++)
00397 {
00398 dirty_mesh[img].val = true;
00399 }
00400 }
00401 }
00402 }
00403
00404
00405 void VisualizationState::Redraw()
00406 {
00407 DEBUG_DEBUG("REDRAW OUT");
00408 if (RequireDraw())
00409 {
00410 DEBUG_DEBUG("REDRAW IN");
00411 RefreshFunc(refreshArg);
00412 }
00413 }
00414
00415 bool VisualizationState::RequireRecalculateViewport()
00416 {
00417 return dirty_viewport;
00418 }
00419
00420 bool VisualizationState::RequireRecalculateMesh (unsigned int image_nr)
00421 {
00422
00423 unsigned int number_of_images = m_pano->getNrOfImages();
00424 if (number_of_images > image_nr)
00425 {
00426 return dirty_mesh[image_nr].val;
00427 }
00428
00429
00430 return true;
00431 }
00432
00433
00434 bool VisualizationState::RequireDraw()
00435 {
00436 return (dirty_draw);
00437 }
00438
00439 void VisualizationState::ForceRequireRedraw()
00440 {
00441 dirty_draw = true;
00442 }
00443
00444 void VisualizationState::FinishedDraw()
00445 {
00446 DEBUG_DEBUG("VIS State Finished draw");
00447 dirty_mesh.clear();
00448 dirty_viewport = false;
00449 dirty_draw = false;
00450 m_view_state->FinishedDraw();
00451 }
00452
00453 void VisualizationState::DoUpdates()
00454 {
00455 DEBUG_DEBUG("BEGIN UPDATES");
00456 m_view_state->DoUpdates();
00457 DEBUG_DEBUG("END UPDATES");
00458 m_mesh_manager->CheckUpdate();
00459 DEBUG_DEBUG("END UPDATES");
00460 }
00461
00462 unsigned int VisualizationState::GetMeshDisplayList(unsigned int image_number)
00463 {
00464 return m_mesh_manager->GetDisplayList(image_number);
00465 }
00466
00467
00468 HuginBase::PanoramaOptions * VisualizationState::GetOptions()
00469 {
00470 return m_view_state->GetOptions();
00471 }
00472
00473 OutputProjectionInfo * VisualizationState::GetProjectionInfo()
00474 {
00475 return m_view_state->GetProjectionInfo();
00476 }
00477
00478 HuginBase::SrcPanoImage * VisualizationState::GetSrcImage(unsigned int image_nr)
00479 {
00480 return m_view_state->GetSrcImage(image_nr);
00481 }
00482
00483
00484
00485 PanosphereOverviewVisualizationState::PanosphereOverviewVisualizationState(PT::Panorama* pano, ViewState* view_state, GLViewer * viewer, void (*RefreshFunction)(void*), void *arg)
00486 : OverviewVisualizationState(pano, view_state, viewer, RefreshFunction, arg, (PanosphereOverviewMeshManager*) NULL)
00487 {
00488 scale = 1;
00489
00490 angx = M_PI / 2.0;
00491 angy = 0;
00492 fov = 40;
00493 R = 500;
00494 sphere_radius = 100;
00495
00496 opts = (*(m_view_state->GetOptions()));
00497 opts.setProjection(HuginBase::PanoramaOptions::EQUIRECTANGULAR);
00498 opts.setHFOV(360.0);
00499 opts.setVFOV(180.0);
00500 projection_info = new OutputProjectionInfo(&opts);
00501 }
00502
00503 PanosphereOverviewVisualizationState::~PanosphereOverviewVisualizationState()
00504 {
00505 delete projection_info;
00506 }
00507
00508 HuginBase::PanoramaOptions * PanosphereOverviewVisualizationState::GetOptions()
00509 {
00510 return &opts;
00511 }
00512
00513 OutputProjectionInfo *PanosphereOverviewVisualizationState::GetProjectionInfo()
00514 {
00515 return projection_info;
00516 }
00517
00518 void PanosphereOverviewVisualizationState::SetOptions(const HuginBase::PanoramaOptions * new_opts)
00519 {
00520 opts = *new_opts;
00521 opts.setProjection(HuginBase::PanoramaOptions::EQUIRECTANGULAR);
00522 opts.setHFOV(360.0);
00523 opts.setVFOV(180.0);
00524 delete projection_info;
00525 projection_info = new OutputProjectionInfo(&opts);
00526 }
00527
00528 void PanosphereOverviewVisualizationState::setAngX(double angx_in)
00529 {
00530 angx = angx_in;
00531 dirty_draw = true;
00532 }
00533
00534 void PanosphereOverviewVisualizationState::setAngY(double angy_in)
00535 {
00536 angy = angy_in;
00537 dirty_draw = true;
00538 }
00539
00540
00541 PlaneOverviewVisualizationState::PlaneOverviewVisualizationState(PT::Panorama* pano, ViewState* view_state, GLViewer * viewer, void (*RefreshFunction)(void*), void *arg)
00542 : OverviewVisualizationState(pano, view_state, viewer, RefreshFunction, arg, (PlaneOverviewMeshManager*) NULL)
00543 {
00544
00545 scale = 1;
00546
00547 fov = 60;
00548 R = 500;
00549 X = 0;
00550 Y = 0;
00551
00552 opts = (*(m_view_state->GetOptions()));
00553 opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00554
00555 opts.setHFOV(90.0);
00556 opts.setVFOV(90.0);
00557 projection_info = new OutputProjectionInfo(&opts);
00558 }
00559
00560 PlaneOverviewVisualizationState::~PlaneOverviewVisualizationState()
00561 {
00562 delete projection_info;
00563 }
00564
00565 HuginBase::PanoramaOptions * PlaneOverviewVisualizationState::GetOptions()
00566 {
00567 return &opts;
00568 }
00569
00570 OutputProjectionInfo *PlaneOverviewVisualizationState::GetProjectionInfo()
00571 {
00572 return projection_info;
00573 }
00574
00575 void PlaneOverviewVisualizationState::SetOptions(const HuginBase::PanoramaOptions * new_opts)
00576 {
00577 opts = *new_opts;
00578 opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00579 opts.setHFOV(90.0);
00580 opts.setVFOV(90.0);
00581 delete projection_info;
00582 projection_info = new OutputProjectionInfo(&opts);
00583 }
00584
00585