ToolHelper.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00026 #include "ToolHelper.h"
00027 #include "Tool.h"
00028 #include "GLPreviewFrame.h"
00029 #include "GLViewer.h"
00030 #include "MeshManager.h"
00031 
00032 ToolHelper::ToolHelper(HuginBase::Panorama *pano_in,
00033                                      VisualizationState *visualization_state_in,
00034                                      GLPreviewFrame *frame_in)
00035 {
00036     pano = pano_in;
00037     visualization_state = visualization_state_in;
00038     frame = frame_in;
00039     images_under_mouse_current = false;
00040     mouse_over_pano = false;
00041     mouse_screen_x = 0;
00042     mouse_screen_y = 0;
00043     mouse_pano_x = 0;
00044     mouse_pano_y = 0;
00045 }
00046 
00047 ToolHelper::~ToolHelper()
00048 {
00049 }
00050 
00051 std::set<Tool *> ToolHelper::ActivateTool(Tool *tool)
00052 {
00053     tools_deactivated.clear();
00054     tool->Activate();
00055     return tools_deactivated;
00056 }
00057 
00058 void ToolHelper::DeactivateTool(Tool *tool)
00059 {
00060     tools_deactivated.insert(tool);
00061     // To deactivate it we need to give up all of its notifications.
00062     RemoveTool(tool, &mouse_button_notified_tools);
00063     RemoveTool(tool, &keypress_notified_tools);
00064     RemoveTool(tool, &mouse_move_notified_tools);
00065     RemoveTool(tool, &draw_under_notified_tools);
00066     RemoveTool(tool, &draw_over_notified_tools);
00067     RemoveTool(tool, &image_draw_begin_tools);
00068     RemoveTool(tool, &image_draw_end_tools);
00069     RemoveTool(tool, &images_under_mouse_notified_tools);
00070     RemoveTool(tool, &really_draw_over_notified_tools);
00071 }
00072 
00073 void ToolHelper::MouseMoved(int x, int y, wxMouseEvent & e)
00074 {
00075     mouse_screen_x = x;
00076     mouse_screen_y = y;
00077     // now tell tools that want notification.
00078     for (auto& tool : mouse_move_notified_tools)
00079     {
00080         tool->MouseMoveEvent(mouse_screen_x, mouse_screen_y, e);
00081     }
00082     // If the mouse has moved, then we don't know what is underneath it anoymore
00083     InvalidateImagesUnderMouse();
00084 }
00085 
00086 void ToolHelper::InvalidateImagesUnderMouse()
00087 {
00088     images_under_mouse_current = false;
00089     // if there are tools that want to know when the images under the mouse
00090     // pointer change, we better detect the images and notfiy them is applicable
00091     if (!images_under_mouse_notified_tools.empty())
00092     {
00093         // there are tools that want to know... so find out:
00094         std::set<unsigned int> old_images_under_mouse = images_under_mouse;
00095         UpdateImagesUnderMouse();
00096         if (old_images_under_mouse != images_under_mouse)
00097         {
00098             // The list has changed. Notifiy all tools that requested it.
00099             for (auto& tool : images_under_mouse_notified_tools)
00100             {
00101                 tool->ImagesUnderMouseChangedEvent();
00102             }
00103         }
00104     }
00105 }
00106 
00107 void ToolHelper::MouseButtonEvent(wxMouseEvent &e)
00108 {
00109     for (auto& tool : mouse_button_notified_tools)
00110     {
00111         tool->MouseButtonEvent(e);
00112     }
00113 }
00114 
00115 void ToolHelper::MouseWheelEvent(wxMouseEvent &e)
00116 {
00117     for (auto& tool : mouse_wheel_notified_tools)
00118     {
00119         tool->MouseWheelEvent(e);
00120     }
00121 }
00122 
00123 
00124 void ToolHelper::KeypressEvent(int keycode, int modifiers, bool pressed)
00125 {
00126     for (auto& tool : keypress_notified_tools)
00127     {
00128         tool->KeypressEvent(keycode, modifiers, pressed);
00129     }
00130 }
00131 
00132 void ToolHelper::BeforeDrawImages()
00133 {
00134     // let all tools that want to draw under the images do so.
00135     for (auto& tool : draw_under_notified_tools)
00136     {
00137         tool->BeforeDrawImagesEvent();
00138     }
00139     // Since we are drawing a new frame, lets assume something has changed,
00140     // however we want to keep with no images under the mouse if the mouse is
00141     // not on the panorama.
00142     if (mouse_over_pano)
00143     {
00144         InvalidateImagesUnderMouse();
00145     }
00146 }
00147 
00148 void ToolHelper::AfterDrawImages()
00149 {
00150     // let all tools that want to draw on top of the images do so.
00151     for (auto& tool : draw_over_notified_tools)
00152     {
00153         tool->AfterDrawImagesEvent();
00154     }
00155     // The overlays are done separetly to avoid errors with blending order.
00156     for (auto& tool : really_draw_over_notified_tools)
00157     {
00158         tool->ReallyAfterDrawImagesEvent();
00159     }
00160 }
00161 
00162 void ToolHelper::MarkDirty()
00163 {
00164     // let all tools that want to draw on top of the images do so.
00165     for (auto& tool : m_tools_need_dirty_flag)
00166     {
00167         tool->MarkDirty();
00168     }
00169 }
00170 
00171 bool ToolHelper::BeforeDrawImageNumber(unsigned int image)
00172 {
00173     if (image_draw_begin_tools.size() > image)
00174     {
00175         if (!image_draw_begin_tools[image].empty())
00176         {
00177             bool result = true;
00178             // BeforeDrawImageEvent can change image_draw_begin_tools[image]
00179             // so we create a copy before to process all dependent tools, also 
00180             // when the set is modified in the BeforeDrawImageEvent function
00181             const auto tools = image_draw_begin_tools[image];
00182             for (auto tool : tools)
00183             {
00184                 result &= tool->BeforeDrawImageEvent(image);
00185             };
00186             return result;
00187         }
00188     }
00189     return true;
00190 }
00191 
00192 void ToolHelper::AfterDrawImageNumber(unsigned int image)
00193 {
00194     if (image_draw_end_tools.size() > image)
00195     {
00196         if (!image_draw_end_tools[image].empty())
00197         {
00198             const auto tools = image_draw_end_tools[image];
00199             for (auto tool : tools)
00200             {
00201                 tool->BeforeDrawImageEvent(image);
00202             }
00203         }
00204     }
00205 }
00206 
00207 void ToolHelper::MouseEnter(int x, int y, wxMouseEvent &e)
00208 {
00209     // You might expect that this is redundant, because any MouseEnter will be
00210     // accompanied by a MouseMove, which will achieve the same ends.  However,
00211     // this is not so.  It's possible for the mouse to enter without moving.
00212     // Morevover, some environments will trigger a MouseLeave+MouseEnter just
00213     // before a MouseButton event; handling this is particularly critical for
00214     // such cases.
00215     mouse_over_pano = true;
00216     mouse_screen_x = x;
00217     mouse_screen_y = y;
00218     // If the mouse has moved, then we don't know what is underneath it anoymore
00219     InvalidateImagesUnderMouse();
00220 }
00221 
00222 void ToolHelper::MouseLeave()
00223 {
00224     // if the mouse leaves the preview, there are no images under the mouse
00225     // pointer anymore.
00226     mouse_over_pano = false;
00227     images_under_mouse.clear();
00228     images_under_mouse_current = true;
00229     if (!images_under_mouse_notified_tools.empty())
00230     {
00231         // notify tools that the set has changed.
00232         for (auto& tool : images_under_mouse_notified_tools)
00233         {
00234             tool->ImagesUnderMouseChangedEvent();
00235         }        
00236     }
00237 }
00238 
00239 
00240 std::set<unsigned int> ToolHelper::GetImageNumbersUnderMouse()
00241 {
00242     if (!images_under_mouse_current)
00243     {
00244         UpdateImagesUnderMouse();
00245     }
00246     return images_under_mouse;
00247 }
00248 
00249 hugin_utils::FDiff2D ToolHelper::GetMouseScreenPosition()
00250 {
00251     return hugin_utils::FDiff2D(mouse_screen_x, mouse_screen_y);
00252 }
00253 
00254 hugin_utils::FDiff2D ToolHelper::GetMousePanoPosition()
00255 {
00256     return hugin_utils::FDiff2D(mouse_pano_x, mouse_pano_y);
00257 }
00258 
00259 VisualizationState *ToolHelper::GetVisualizationStatePtr()
00260 {
00261     return visualization_state;
00262 }
00263 
00264 ViewState *ToolHelper::GetViewStatePtr()
00265 {
00266     return visualization_state->getViewState();
00267 }
00268 
00269 HuginBase::Panorama *ToolHelper::GetPanoramaPtr()
00270 {
00271     return pano;
00272 }
00273 
00274 void ToolHelper::NotifyMe(Event event, Tool *tool)
00275 {
00276     switch (event)
00277     {
00278         case MOUSE_MOVE:
00279             AddTool(tool, &mouse_move_notified_tools);
00280             break;
00281         case MOUSE_PRESS:
00282             AddTool(tool, &mouse_button_notified_tools);
00283             break;
00284         case MOUSE_WHEEL:
00285             AddTool(tool, &mouse_wheel_notified_tools);
00286             break;
00287         case KEY_PRESS:
00288             AddTool(tool, &keypress_notified_tools);
00289             break;
00290         case DRAW_UNDER_IMAGES:
00291             AddTool(tool, &draw_under_notified_tools);
00292             break;
00293         case DRAW_OVER_IMAGES:
00294             AddTool(tool, &draw_over_notified_tools);
00295             break;
00296         case IMAGES_UNDER_MOUSE_CHANGE:
00297             AddTool(tool, &images_under_mouse_notified_tools);
00298             break;
00299         case REALLY_DRAW_OVER_IMAGES:
00300             AddTool(tool, &really_draw_over_notified_tools);
00301             break;
00302         case MARK_DIRTY:
00303             AddTool(tool, &m_tools_need_dirty_flag);
00304             break;
00305     }   
00306 }
00307 
00308 void ToolHelper::NotifyMeBeforeDrawing(unsigned int image_nr,
00309                                               Tool *tool)
00310 {
00311     AddTool(tool, &image_draw_begin_tools, image_nr);
00312 }
00313 
00314 void ToolHelper::NotifyMeAfterDrawing(unsigned int image_nr,
00315                                              Tool *tool)
00316 {
00317     AddTool(tool, &image_draw_end_tools, image_nr);
00318 }
00319 
00320 void ToolHelper::DoNotNotifyMe(Event event, Tool *tool)
00321 {
00322     // TODO we should probably check that the tools have the notification they
00323     // are trying to give up, as misbehaving tools could break another tool.
00324     switch (event)
00325     {
00326         case MOUSE_MOVE:
00327             RemoveTool(tool, &mouse_move_notified_tools);
00328             break;
00329         case MOUSE_PRESS:
00330             RemoveTool(tool, &mouse_button_notified_tools);
00331             break;
00332         case MOUSE_WHEEL:
00333             RemoveTool(tool, &mouse_wheel_notified_tools);
00334             break;
00335         case KEY_PRESS:
00336             RemoveTool(tool, &keypress_notified_tools);
00337             break;
00338         case DRAW_UNDER_IMAGES:
00339             RemoveTool(tool, &draw_under_notified_tools);
00340             break;
00341         case DRAW_OVER_IMAGES:
00342             RemoveTool(tool, &draw_over_notified_tools);
00343             break;
00344         case IMAGES_UNDER_MOUSE_CHANGE:
00345             RemoveTool(tool, &images_under_mouse_notified_tools);
00346             break;
00347         case REALLY_DRAW_OVER_IMAGES:
00348             RemoveTool(tool, &really_draw_over_notified_tools);
00349             break;
00350         case MARK_DIRTY:
00351             RemoveTool(tool, &m_tools_need_dirty_flag);
00352             break;
00353     }   
00354 }
00355 
00356 void ToolHelper::DoNotNotifyMeBeforeDrawing(unsigned int image_nr,
00357                                               Tool *tool)
00358 {
00359     RemoveTool(tool, &image_draw_begin_tools, image_nr);
00360 }
00361 
00362 void ToolHelper::DoNotNotifyMeAfterDrawing(unsigned int image_nr,
00363                                              Tool *tool)
00364 {
00365     RemoveTool(tool, &image_draw_end_tools, image_nr);
00366 }
00367 
00368 void ToolHelper::SetStatusMessage(wxString message)
00369 {
00370     // get the GLPreviewFrame to set its status bar's text.
00371     frame->SetStatusMessage(message);
00372 }
00373 
00374 
00375 // These functions remove tools from various things that keep pointers to them
00376 // so that they can be notified. They are called when we don't want to notify
00377 // them anymore.
00378 
00379 void ToolHelper::RemoveTool(Tool *tool, Tool **single)
00380 {
00381     if (*single == tool)
00382     {
00383         *single = 0;
00384     }
00385 }
00386 
00387 void ToolHelper::RemoveTool(Tool *tool,
00388                                    std::set<Tool *> *set)
00389 {
00390     auto foundTool = set->find(tool);
00391     if (foundTool != set->end())
00392     {
00393         set->erase(foundTool);
00394     }
00395 }
00396 
00397 void ToolHelper::RemoveTool(Tool *tool,
00398                                   std::vector<std::set<Tool *> > *vector)
00399 {
00400     // check every item for presence.
00401     for (unsigned int image = 0; image < vector->size(); image++)
00402     {
00403         (*vector)[image].erase(tool);
00404     }
00405 }
00406 
00407 void ToolHelper::RemoveTool(Tool *tool,
00408                                   std::vector<std::set<Tool *> > *vector,
00409                                   unsigned int index)
00410 {
00411     if (vector->size() > index)
00412     {
00413         (*vector)[index].erase(tool);
00414     }
00415 }
00416 
00417 void ToolHelper::AddTool(Tool *tool, Tool **single)
00418 {
00419     if (*single != 0 || *single == tool)
00420     {
00421         DeactivateTool(*single);
00422     }
00423     *single = tool;
00424 }
00425 
00426 void ToolHelper::AddTool(Tool *tool, std::set<Tool *> *set)
00427 {
00428     set->insert(tool);
00429 }
00430 
00431 void ToolHelper::AddTool(Tool *tool,
00432                                std::vector<std::set<Tool *> > *vector,
00433                                unsigned int index)
00434 {
00435     if (vector->size() < index + 1)
00436     {
00437         // increase the size of the vector to handle enough elements for index
00438         // to exist
00439         vector->resize(index + 1, std::set<Tool*>());
00440     }
00441 //    else if ((*vector)[index] && (*vector)[index] != tool)
00442 //    {
00443 //        // if a different tool already was doing this, deactivate it.
00444 //        DeactivateTool((*vector)[index]);
00445 //    };
00446 //    (*vector)[index] = tool;
00447     (*vector)[index].insert(tool);
00448 }
00449 
00450 
00451 void PreviewToolHelper::MouseMoved(int x, int y, wxMouseEvent &e)
00452 {
00453     mouse_over_pano = true;
00454     mouse_screen_x = x;
00455     mouse_screen_y = y;
00456     // work out where the pointer is in the panorama.
00457     vigra::Rect2D visible = visualization_state->GetVisibleArea();
00458     mouse_pano_x = (double) x / visualization_state->GetScale() + (double) visible.left();
00459     mouse_pano_y = (double) y / visualization_state->GetScale() + (double) visible.top();
00460     // now tell tools that want notification.
00461     for (auto& tool : mouse_move_notified_tools)
00462     {
00463         tool->MouseMoveEvent(mouse_pano_x, mouse_pano_y, e);
00464     }
00465     // If the mouse has moved, then we don't know what is underneath it anoymore
00466     InvalidateImagesUnderMouse();
00467 }
00468 
00469 void PreviewToolHelper::UpdateImagesUnderMouse()
00470 {
00471     // We want to find out which images cover the point underneath the mouse
00472     // pointer.
00473     images_under_mouse.clear();
00474     if (IsMouseOverPano()) {
00475         unsigned int num_images = pano->getNrOfImages();
00476         std::set<unsigned int> displayedImages = pano->getActiveImages();
00477         for (unsigned int image_index = 0; image_index < num_images; image_index++)
00478         {
00479             // don't try any images that are turned off
00480             if (displayedImages.count(image_index))
00481             {
00482                 // work out if the image covers the point under the mouse.
00483                 HuginBase::PTools::Transform transform;
00484                 transform.createTransform(*visualization_state->GetSrcImage(image_index),
00485                                           *visualization_state->GetOptions());
00486                 double image_x, image_y;
00487                 transform.transformImgCoord(image_x, image_y, mouse_pano_x, mouse_pano_y);
00488                 if (visualization_state->getViewState()->GetSrcImage(image_index)->isInside(vigra::Point2D(
00489                                                       int(image_x), int (image_y))))
00490                 {
00491                     // this image is under the mouse, add it to the set.
00492                     images_under_mouse.insert(image_index);
00493                 }
00494             }
00495         }
00496     }
00497     images_under_mouse_current = true;
00498 }
00499 
00500 void PanosphereOverviewToolHelper::UpdateImagesUnderMouse()
00501 {
00502     images_under_mouse.clear();
00503     if (IsMouseOverPano()) {
00504         unsigned int num_images = pano->getNrOfImages();
00505         std::set<unsigned int> displayedImages = pano->getActiveImages();
00506         for (unsigned int image_index = 0; image_index < num_images; image_index++)
00507         {
00508             // don't try any images that are turned off
00509             if (displayedImages.count(image_index))
00510             {
00511                 // work out if the image covers the point under the mouse.
00512                 HuginBase::PTools::Transform transform;
00513                 transform.createTransform(*visualization_state->GetSrcImage(image_index),
00514                                           *visualization_state->GetOptions());
00515                 double image_x, image_y;
00516                 transform.transformImgCoord(image_x, image_y, mouse_pano_x, mouse_pano_y);
00517                 if (visualization_state->getViewState()->GetSrcImage(image_index)->isInside(vigra::Point2D(
00518                                                       int(image_x), int (image_y))))
00519                 {
00520                     // this image is under the mouse, add it to the set.
00521                     images_under_mouse.insert(image_index);
00522                 }
00523             }
00524         }
00525     }
00526     images_under_mouse_current = true;
00527 }
00528 
00529 void PanosphereOverviewToolHelper::MouseMoved(int x, int y, wxMouseEvent & e)
00530 {
00531     PanosphereOverviewVisualizationState * panostate = static_cast<PanosphereOverviewVisualizationState*>(visualization_state);
00532 
00533     double d = panostate->getR();
00534     double r = panostate->getSphereRadius();
00535 
00536     int tcanv_w, tcanv_h;
00537     panostate->GetViewer()->GetClientSize(&tcanv_w,&tcanv_h);
00538 
00539     double canv_w, canv_h;
00540     canv_w = tcanv_w;
00541     canv_h = tcanv_h;
00542     
00543     double fov = panostate->getFOV();
00544 
00545     double fovy, fovx;
00546     if (canv_w > canv_h) {
00547         fovy = DEG_TO_RAD(fov);
00548         fovx = 2 * atan( tan(fovy / 2.0) * canv_w / canv_h);
00549     } else {
00550         fovx = DEG_TO_RAD(fov);
00551         fovy = 2 * atan( tan(fovx / 2.0) * canv_h / canv_w);
00552     }
00553 
00554     double ax = tan(fovx / 2.0) * d * (x / (canv_w / 2.0) - 1);
00555     double ay = tan(fovy / 2.0) * d * (y / (canv_h / 2.0) - 1);
00556 
00557     double a_limit = r * d / sqrt(d*d - r*r);
00558 
00559     if (ax*ax + ay*ay < a_limit*a_limit) {
00560 
00561         mouse_over_pano = true;
00562 
00563         double ta,tb,tc;
00564         ta = (ax*ax + ay*ay) / (d*d) + 1;
00565         tb = - 2 * (ax*ax + ay*ay) / d;
00566         tc = ax*ax + ay*ay - r*r;
00567 
00568         double pz = ( -tb + sqrt(tb*tb - 4*ta*tc) ) / ( 2 * ta );
00569         double px = ax * (d - pz) / d;
00570         double py = ay * (d - pz) / d;
00571 
00572         double pl = sqrt(px*px + py*py + pz*pz);
00573 
00574         double pang_yaw = -atan(px / pz);
00575         double pang_pitch = asin(py / pl);
00576 
00577         double ang_yaw = panostate->getAngX();
00578         double ang_pitch = panostate->getAngY();
00579 
00580         double x,y,z;
00581         x = sin(ang_yaw)*cos(ang_pitch);
00582         z = cos(ang_yaw)*cos(ang_pitch);
00583         y = sin(ang_pitch);
00584 
00585         Vector3 vec(x,y,z);
00586 
00587         Vector3 top(0,1,0);
00588 
00589         Vector3 ptop = vec.Cross(top).Cross(vec).GetNormalized();
00590 
00591         Vector3 tres;
00592         tres.x = ptop.x*(ptop.x * vec.x + ptop.y*vec.y + ptop.z*vec.z) + cos(pang_yaw) * (ptop.x * (-ptop.y * vec.y - ptop.z * vec.z) + vec.x*(ptop.y*ptop.y + ptop.z*ptop.z)) + sin(pang_yaw) * (-ptop.z*vec.y + ptop.y*vec.z);
00593         tres.y = ptop.y*(ptop.x * vec.x + ptop.y*vec.y + ptop.z*vec.z) + cos(pang_yaw) * (ptop.y * (-ptop.x * vec.x - ptop.z * vec.z) + vec.y*(ptop.x*ptop.x + ptop.z*ptop.z)) + sin(pang_yaw) * (-ptop.z*vec.x + ptop.x*vec.z);
00594         tres.z = ptop.z*(ptop.x * vec.x + ptop.y*vec.y + ptop.z*vec.z) + cos(pang_yaw) * (ptop.z * (-ptop.x * vec.x - ptop.y * vec.y) + vec.z*(ptop.x*ptop.x + ptop.y*ptop.y)) + sin(pang_yaw) * (-ptop.y*vec.x + ptop.x*vec.y);
00595 
00596         Vector3 pside = ptop.Cross(tres).GetNormalized();
00597         Vector3 res;
00598 
00599         res.x = pside.x*(pside.x * tres.x + pside.y*tres.y + pside.z*tres.z) + cos(pang_pitch) * (pside.x * (-pside.y * tres.y - pside.z * tres.z) + tres.x*(pside.y*pside.y + pside.z*pside.z)) + sin(pang_pitch) * (-pside.z*tres.y + pside.y*tres.z);
00600         res.y = pside.y*(pside.x * tres.x + pside.y*tres.y + pside.z*tres.z) + cos(pang_pitch) * (pside.y * (-pside.x * tres.x - pside.z * tres.z) + tres.y*(pside.x*pside.x + pside.z*pside.z)) + sin(-pang_pitch) * (-pside.z*tres.x + pside.x*tres.z);
00601         res.z = pside.z*(pside.x * tres.x + pside.y*tres.y + pside.z*tres.z) + cos(pang_pitch) * (pside.z * (-pside.x * tres.x - pside.y * tres.y) + tres.z*(pside.x*pside.x + pside.y*pside.y)) + sin(pang_pitch) * (-pside.y*tres.x + pside.x*tres.y);
00602 
00603         double yaw, pitch;
00604         pitch = asin(res.y);
00605         yaw = atan2(res.x , res.z);
00606 
00607         yaw += M_PI / 2.0;
00608         if (yaw < 0) yaw += 2 * M_PI;
00609         if (yaw > 2 * M_PI) yaw -= 2 * M_PI;
00610 
00611         pitch += M_PI / 2.0;
00612         pitch = M_PI - pitch;
00613 
00614         mouse_pano_x = yaw / (2 * M_PI) * panostate->GetOptions()->getWidth();
00615         mouse_pano_y = pitch / (M_PI) * panostate->GetOptions()->getHeight();
00616 
00618 
00619 //        cerr << "mouse " << mouse_pano_x << " " << mouse_pano_y << " ; " << canv_w << " " << canv_h);
00620 
00621 //        double t_mouse_pano_x = yaw M
00622 
00623     } else {
00624 
00625         mouse_over_pano = false;
00626     }
00627     
00628     ToolHelper::MouseMoved(x,y,e);
00629 }
00630 
00631 PanosphereOverviewToolHelper::PanosphereOverviewToolHelper(HuginBase::Panorama *pano,
00632                   VisualizationState *visualization_state,
00633                   GLPreviewFrame * frame) : OverviewToolHelper(pano, visualization_state, frame) {}
00634 
00635 PanosphereOverviewToolHelper::~PanosphereOverviewToolHelper() {}
00636 
00637 void PanosphereOverviewToolHelper::NotifyMe(PanosphereOverviewEvent event, PanosphereOverviewTool * tool) {
00638     switch (event) {
00639         case DRAW_OVER_IMAGES_BACK:
00640             AddTool(tool, &draw_over_notified_tools_back);
00641         break;
00642         case DRAW_OVER_IMAGES_FRONT:
00643             AddTool(tool, &draw_over_notified_tools_front);
00644         break;
00645         case DRAW_UNDER_IMAGES_BACK:
00646             AddTool(tool, &draw_under_notified_tools_back);
00647         break;
00648         case DRAW_UNDER_IMAGES_FRONT:
00649             AddTool(tool, &draw_under_notified_tools_front);
00650         break;
00651     }
00652 }
00653 
00654 void PanosphereOverviewToolHelper::DoNotNotifyMe(PanosphereOverviewEvent event, PanosphereOverviewTool * tool) {
00655     switch (event) {
00656         case DRAW_OVER_IMAGES_BACK:
00657             RemoveTool(tool, &draw_over_notified_tools_back);
00658         break;
00659         case DRAW_OVER_IMAGES_FRONT:
00660             RemoveTool(tool, &draw_over_notified_tools_front);
00661         break;
00662         case DRAW_UNDER_IMAGES_BACK:
00663             RemoveTool(tool, &draw_under_notified_tools_back);
00664         break;
00665         case DRAW_UNDER_IMAGES_FRONT:
00666             RemoveTool(tool, &draw_under_notified_tools_front);
00667         break;
00668     }
00669 }
00670 
00671 void PanosphereOverviewToolHelper::BeforeDrawImagesBack()
00672 {
00673     for (auto& tool : draw_under_notified_tools_back)
00674     {
00675         static_cast<PanosphereOverviewTool*>(tool)->BeforeDrawImagesBackEvent();
00676     }
00677 }
00678 
00679 void PanosphereOverviewToolHelper::BeforeDrawImagesFront()
00680 {
00681     for (auto& tool : draw_under_notified_tools_front)
00682     {
00683         static_cast<PanosphereOverviewTool*>(tool)->BeforeDrawImagesFrontEvent();
00684     }
00685 }
00686 
00687 void PanosphereOverviewToolHelper::AfterDrawImagesBack()
00688 {
00689     for (auto& tool : draw_over_notified_tools_back)
00690     {
00691         static_cast<PanosphereOverviewTool*>(tool)->AfterDrawImagesBackEvent();
00692     }
00693 }
00694 
00695 void PanosphereOverviewToolHelper::AfterDrawImagesFront()
00696 {
00697     for (auto& tool : draw_over_notified_tools_front)
00698     {
00699         static_cast<PanosphereOverviewTool*>(tool)->AfterDrawImagesFrontEvent();
00700     }
00701 }
00702 
00703 void PanosphereOverviewToolHelper::DeactivateTool(Tool *tool)
00704 {
00705     ToolHelper::DeactivateTool(tool);
00706 
00707     RemoveTool(tool, &draw_under_notified_tools_back);
00708     RemoveTool(tool, &draw_under_notified_tools_front);
00709     RemoveTool(tool, &draw_over_notified_tools_back);
00710     RemoveTool(tool, &draw_over_notified_tools_front);
00711 }
00712 
00713 
00714 PlaneOverviewToolHelper::PlaneOverviewToolHelper(HuginBase::Panorama *pano,
00715                   VisualizationState *visualization_state,
00716                   GLPreviewFrame * frame) : OverviewToolHelper(pano, visualization_state, frame) {}
00717 
00718 PlaneOverviewToolHelper::~PlaneOverviewToolHelper() {}
00719 
00720 void PlaneOverviewToolHelper::MouseMoved(int x, int y, wxMouseEvent & e)
00721 {
00722 
00723     PlaneOverviewVisualizationState * panostate = static_cast<PlaneOverviewVisualizationState*>(visualization_state);
00724 
00725     double d = panostate->getR();
00726 
00727     int tcanv_w, tcanv_h;
00728     panostate->GetViewer()->GetClientSize(&tcanv_w,&tcanv_h);
00729 
00730     double canv_w, canv_h;
00731     canv_w = tcanv_w;
00732     canv_h = tcanv_h;
00733     
00734     double fov = panostate->getFOV();
00735 
00736     double fovy, fovx;
00737     if (canv_w > canv_h) {
00738         fovy = DEG_TO_RAD(fov);
00739         fovx = 2 * atan( tan(fovy / 2.0) * canv_w / canv_h);
00740     } else {
00741         fovx = DEG_TO_RAD(fov);
00742         fovy = 2 * atan( tan(fovx / 2.0) * canv_h / canv_w);
00743     }
00744 
00745     double vis_w, vis_h;
00746     vis_w = 2.0 * tan ( fovx / 2.0 ) * d;
00747     vis_h = 2.0 * tan ( fovy / 2.0 ) * d;
00748 
00749     //position of the mouse on the z=0 plane
00750     double prim_x, prim_y;
00751     prim_x = (double) x / canv_w * vis_w - vis_w / 2.0 + panostate->getX();
00752     prim_y = ((double) y / canv_h * vis_h - vis_h / 2.0 - panostate->getY());
00753 
00754 //    std::cout << "mouse ov" << plane_x << " " << plane_y << std::endl;
00755     plane_x = prim_x;
00756     plane_y = prim_y;
00757 
00758     double width, height;
00759     HuginBase::PanoramaOptions * opts = panostate->GetOptions();
00760     width = opts->getWidth();
00761     height = opts->getHeight();
00762 
00763     mouse_pano_x = prim_x / MeshManager::PlaneOverviewMeshInfo::scale * width + width / 2.0;
00764     mouse_pano_y = prim_y / MeshManager::PlaneOverviewMeshInfo::scale * width + height / 2.0;
00765 
00766 //    std::cout << "plane mouse " << mouse_pano_x << " " << mouse_pano_y << " ; " << prim_x << " " << prim_y << " ; " << width << " " << height << std::endl;
00767 //    cerr << "plane mouse " << mouse_pano_x << " " << mouse_pano_y);
00768 
00769     mouse_over_pano = true;
00770     
00771     ToolHelper::MouseMoved(x,y,e);
00772 }
00773 
00774 void PlaneOverviewToolHelper::UpdateImagesUnderMouse()
00775 {
00776     images_under_mouse.clear();
00777     if (IsMouseOverPano()) {
00778         unsigned int num_images = pano->getNrOfImages();
00779         std::set<unsigned int> displayedImages = pano->getActiveImages();
00780         for (unsigned int image_index = 0; image_index < num_images; image_index++)
00781         {
00782             // don't try any images that are turned off
00783             if (displayedImages.count(image_index))
00784             {
00785                 // work out if the image covers the point under the mouse.
00786                 HuginBase::PTools::Transform transform;
00787                 transform.createTransform(*visualization_state->GetSrcImage(image_index),
00788                                           *visualization_state->GetOptions());
00789                 double image_x, image_y;
00790                 transform.transformImgCoord(image_x, image_y, mouse_pano_x, mouse_pano_y);
00791                 if (visualization_state->getViewState()->GetSrcImage(image_index)->isInside(vigra::Point2D(
00792                                                       int(image_x), int (image_y))))
00793                 {
00794                     // this image is under the mouse, add it to the set.
00795                     images_under_mouse.insert(image_index);
00796                 }
00797             }
00798         }
00799     }
00800     images_under_mouse_current = true;
00801 
00802 }
00803 
00804 

Generated on 30 Jun 2016 for Hugintrunk by  doxygen 1.4.7