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

Generated on 30 May 2016 for Hugintrunk by  doxygen 1.4.7