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

Generated on 1 May 2016 for Hugintrunk by  doxygen 1.4.7