Revision: 3258
http://hugin.svn.sourceforge.net/hugin/?rev=3258&view=rev
Author: jlegg
Date: 2008-08-01 03:43:35 +0000 (Fri, 01 Aug 2008)
Log Message:
-----------
Mostly things for the identify tool, which isn't complete but has the basic functionality. I've also tried to get the drag tool to keep the point you start dragging under the cursor (where it is not the centre), but it jumps a bit. The TextureManager and MeshManager are now part of the ViewState object, so that tools have easy access to them. Tool's can now be notified of when the set of images under the mouse cursor change, so they don't individually check this for every mouse movement, the PreviewToolHelper does it once each time.
I've fixed a bug with 180 degree boundary correction on an edge where the subdivision level was changing.
I've made all images in an Alber's equal area conic projection use the TexCoordRemapper until I've worked out how to handle all the moving poles and angled seems. This isn't ideal for panoramas with many small images, and leaves a mess around the edge of the projection where I need to do some more clipping. This clipping will be different as it is in the space of the vertices and not the textures, and is specifically to get the shape of the projection.
The identity tool and point to point dragging are not working completely yet, I am commiting mainly as a backup.
Modified Paths:
--------------
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/CMakeLists.txt
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ChoosyRemapper.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshManager.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshRemapper.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewTool.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.h
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/VertexCoordRemapper.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.h
Added Paths:
-----------
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.cpp
hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.h
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/CMakeLists.txt
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/CMakeLists.txt 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/CMakeLists.txt 2008-08-01 03:43:35 UTC (rev 3258)
@@ -32,7 +32,7 @@
HFOVDialog.cpp TextureManager.cpp MeshRemapper.cpp VertexCoordRemapper.cpp
TexCoordRemapper.cpp ChoosyRemapper.cpp MeshManager.cpp ViewState.cpp
OutputProjectionInfo.cpp PreviewToolHelper.cpp PreviewTool.cpp
-PreviewCropTool.cpp PreviewDragTool.cpp)
+PreviewCropTool.cpp PreviewDragTool.cpp PreviewIdentifyTool.cpp)
IF(APPLE)
if (MAC_SELF_CONTAINED_BUNDLE)
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ChoosyRemapper.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ChoosyRemapper.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ChoosyRemapper.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -60,6 +60,7 @@
case HuginBase::PanoramaOptions::STEREOGRAPHIC:
case HuginBase::PanoramaOptions::FULL_FRAME_FISHEYE:
case HuginBase::PanoramaOptions::LAMBERT_AZIMUTHAL:
+ case HuginBase::PanoramaOptions::ALBERS_EQUAL_AREA_CONIC:
// Add any projections where the poles maps to a big set of points here.
// check for pole crossing
{
@@ -76,6 +77,17 @@
{
pole = true; // it covers this pole
}
+ if (opts->getProjection() ==
+ HuginBase::PanoramaOptions::ALBERS_EQUAL_AREA_CONIC)
+ {
+ // always use a TexCoordRemapper for Alber's equal area conic.
+ pole = true;
+ // FIXME This is not sutible for panoramas containing many small
+ // images. To detect the poles in Alber's Equal area conic
+ // projetion, we need to account for their movement with
+ // changing parameters. Also the 180 degree seam goes at a
+ // funny angle, and we need to account for this.
+ }
if (!pole)
{
// check the other pole
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -59,6 +59,7 @@
#include "PreviewTool.h"
#include "PreviewCropTool.h"
#include "PreviewDragTool.h"
+#include "PreviewIdentifyTool.h"
using namespace utils;
@@ -88,6 +89,7 @@
EVT_TOOL(XRCID("preview_photometric_tool"), GLPreviewFrame::OnPhotometric)
EVT_TOOL(XRCID("preview_crop_tool"), GLPreviewFrame::OnCrop)
EVT_TOOL(XRCID("preview_drag_tool"), GLPreviewFrame::OnDrag)
+ EVT_TOOL(XRCID("preview_identify_tool"), GLPreviewFrame::OnIdentify)
EVT_TEXT_ENTER( -1 , GLPreviewFrame::OnTextCtrlChanged)
@@ -102,6 +104,8 @@
#else
EVT_CHECKBOX(-1, GLPreviewFrame::OnChangeDisplayedImgs)
#endif
+ //EVT_ENTER_WINDOW(-1, GLPreviewFrame::MouseEnter)
+
EVT_SCROLL_CHANGED(GLPreviewFrame::OnChangeFOV)
// EVT_SCROLL_THUMBRELEASE(GLPreviewFrame::OnChangeFOV)
// EVT_SCROLL_ENDSCROLL(GLPreviewFrame::OnChangeFOV)
@@ -122,6 +126,13 @@
DEBUG_ASSERT(m_ToolBar);
// create tool bar
SetToolBar(m_ToolBar);
+ drag_tool_id = wxXmlResource::Get()->GetXRCID(wxT("preview_drag_tool"));
+ DEBUG_ASSERT(drag_tool_id != -2);
+ crop_tool_id = wxXmlResource::Get()->GetXRCID(wxT("preview_crop_tool"));
+ DEBUG_ASSERT(crop_tool_id != -2);
+ identify_tool_id = wxXmlResource::Get()->GetXRCID(wxT("preview_identify_tool"));
+ DEBUG_ASSERT(identify_tool_id != -2);
+
m_topsizer = new wxBoxSizer( wxVERTICAL );
@@ -963,6 +974,7 @@
helper = helper_in;
crop_tool = new PreviewCropTool(helper);
drag_tool = new PreviewDragTool(helper);
+ identify_tool = new PreviewIdentifyTool(helper, this);
}
void GLPreviewFrame::OnCrop(wxCommandEvent & e)
@@ -970,8 +982,9 @@
// turn on or off the crop tool when its button is pressed.
if (e.IsChecked())
{
- helper->ActivateTool(crop_tool);
- // TODO deactivate the buttons for tools this turns off.
+ // ActivateTool returns pointers to the tools that were switched off to
+ // enable the crop tool.
+ TurnOffTools(helper->ActivateTool(crop_tool));
} else {
helper->DeactivateTool(crop_tool);
// the tool draws some extra guides that need covering up
@@ -983,10 +996,81 @@
{
if (e.IsChecked())
{
- helper->ActivateTool(drag_tool);
- // TODO deactivate the buttons for tools this turns off.
+ TurnOffTools(helper->ActivateTool(drag_tool));
} else {
helper->DeactivateTool(drag_tool);
}
+ // The plumb lines should only be shown when the tool is active:
+ m_GLViewer->Refresh(); // ...draw them or draw over them.
+}
+
+void GLPreviewFrame::OnIdentify(wxCommandEvent & e)
+{
+ if (e.IsChecked())
+ {
+ TurnOffTools(helper->ActivateTool(identify_tool));
+ } else {
+ helper->DeactivateTool(identify_tool);
+ CleanButtonColours();
+ }
m_GLViewer->Refresh();
}
+
+void GLPreviewFrame::TurnOffTools(std::set<PreviewTool*> tools)
+{
+ std::set<PreviewTool*>::iterator i;
+ for (i = tools.begin(); i != tools.end(); i++)
+ {
+ if (*i == crop_tool)
+ {
+ // disabled the crop tool, toogle the button for it off
+ m_ToolBar->ToggleTool(crop_tool_id, false);
+ // cover up the guidelines
+ m_GLViewer->Refresh();
+ } else if (*i == drag_tool)
+ {
+ // disabled the drag tool, toggle its button off.
+ m_ToolBar->ToggleTool(drag_tool_id, false);
+ // cover up its boxes
+ m_GLViewer->Refresh();
+ } else if (*i == identify_tool)
+ {
+ // disabled the identify tool, toggle its button off.
+ m_ToolBar->ToggleTool(identify_tool_id, false);
+ // cover up its indicators and restore normal button colours.
+ m_GLViewer->Refresh();
+ CleanButtonColours();
+ }
+ }
+}
+
+void GLPreviewFrame::SetImageButtonColour(unsigned int image_nr,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue)
+{
+ if (red || green || blue)
+ {
+ // the identify tool wants us to highlight an image button in the given
+ // colour, to match up with the display in the preview.
+ m_ToggleButtons[image_nr]->SetBackgroundColour(
+ wxColour(red, green, blue));
+ } else {
+ // return to the normal colour
+ m_ToggleButtons[image_nr]->SetBackgroundColour(wxNullColour);
+ }
+ m_ToggleButtons[image_nr]->Refresh();
+}
+
+void GLPreviewFrame::CleanButtonColours()
+{
+ // when we turn off the identification tool, any buttons that were coloured
+ // to match the image in the preview should be given back the system themed
+ // colours.
+ unsigned int nr_images = m_pano.getNrOfImages();
+ for (unsigned image = 0; image < nr_images; image++)
+ {
+ m_ToggleButtons[image]->SetBackgroundColour(wxNullColour);
+ }
+}
+
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLPreviewFrame.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -29,8 +29,10 @@
class GLViewer;
class PreviewToolHelper;
+class PreviewTool;
class PreviewCropTool;
class PreviewDragTool;
+class PreviewIdentifyTool;
/** The OpenGL preview frame
*
@@ -57,6 +59,8 @@
void updateProgressDisplay();
void MakeTools(PreviewToolHelper * helper);
+ void SetImageButtonColour(unsigned int image_nr, unsigned char red,
+ unsigned char green, unsigned char blue);
protected:
void OnClose(wxCloseEvent& e);
@@ -69,6 +73,7 @@
void OnPhotometric(wxCommandEvent & e);
void OnCrop(wxCommandEvent & e);
void OnDrag(wxCommandEvent & e);
+ void OnIdentify(wxCommandEvent &e);
void OnNumTransform(wxCommandEvent & e);
void OnChangeFOV(wxScrollEvent & e);
void OnTrackChangeFOV(wxScrollEvent & e);
@@ -90,6 +95,7 @@
GLViewer * m_GLViewer;
wxToolBar * m_ToolBar;
+ int drag_tool_id, crop_tool_id, identify_tool_id;
wxSlider * m_HFOVSlider;
wxSlider * m_VFOVSlider;
wxChoice * m_BlendModeChoice;
@@ -124,6 +130,9 @@
PreviewToolHelper *helper;
PreviewCropTool *crop_tool;
PreviewDragTool *drag_tool;
+ PreviewIdentifyTool *identify_tool;
+ void TurnOffTools(std::set<PreviewTool*> tools);
+ void CleanButtonColours();
};
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -55,9 +55,8 @@
0, wxT("GLPreviewCanvas"), wxNullPalette)
{
m_glContext = new wxGLContext(this, 0);
-
+
m_renderer = 0;
- m_tex_manager = 0;
m_pano = &pano;
@@ -73,7 +72,6 @@
{
delete m_tool_helper;
delete m_renderer;
- delete m_tex_manager;
delete m_view_state;
}
}
@@ -90,20 +88,9 @@
// that use it... so create those if necessary as well.
if (!started_creation)
{
- started_creation = true;
// It appears we are setting up for the first time.
- // we need something to store the state of the view and control updates
- m_view_state = new ViewState(m_pano, RefreshWrapper, this);
- // Start the tools going:
- m_tool_helper = new PreviewToolHelper(m_pano, m_view_state);
- frame->MakeTools(m_tool_helper);
- // now set the texture manager up.
- m_tex_manager = new TextureManager(*m_pano, m_view_state);
- // same for the mesh manager
- m_mesh_manager = new MeshManager(m_pano, m_view_state);
- // now make a renderer
- m_renderer = new GLRenderer(m_pano, m_tex_manager, m_mesh_manager,
- m_view_state, m_tool_helper);
+ started_creation = true;
+
// initialise the glew library.
GLenum error_state = glewInit();
if (error_state != GLEW_OK)
@@ -116,13 +103,23 @@
if (!GLEW_VERSION_1_3)
{
std::cerr << "Sorry, OpenGL 1.3 is required.\n";
- }
+ }
+
+ // we need something to store the state of the view and control updates
+ m_view_state = new ViewState(m_pano, RefreshWrapper, this);
+ // Start the tools going:
+ m_tool_helper = new PreviewToolHelper(m_pano, m_view_state);
+ frame->MakeTools(m_tool_helper);
+ // now make a renderer
+ m_renderer = new GLRenderer(m_pano, m_view_state->GetTextureManager(),
+ m_view_state->GetMeshManager(),
+ m_view_state, m_tool_helper);
}
}
void GLViewer::SetPhotometricCorrect(bool state)
{
- m_tex_manager->SetPhotometricCorrect(state);
+ m_view_state->GetTextureManager()->SetPhotometricCorrect(state);
Refresh();
}
@@ -172,8 +169,7 @@
GetClientSize(&w, &h);
offset = m_renderer->Resize(w, h);
}
- m_tex_manager->CheckUpdate();
- m_mesh_manager->CheckUpdate();
+ m_view_state->DoUpdates();
m_renderer->Redraw();
glFlush();
SwapBuffers();
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/GLViewer.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -61,8 +61,6 @@
PreviewToolHelper *m_tool_helper;
GLRenderer *m_renderer;
- TextureManager *m_tex_manager;
- MeshManager *m_mesh_manager;
wxGLContext *m_glContext;
PT::Panorama * m_pano;
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshManager.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshManager.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshManager.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -27,7 +27,10 @@
#ifndef _MESHMANAGER_H
#define _MESHMANAGER_H
+#include "PT/Panorama.h"
+
class MeshRemapper;
+class ViewState;
class MeshManager
{
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshRemapper.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshRemapper.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/MeshRemapper.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -162,6 +162,7 @@
const unsigned int v2_index,
const double cl[3]) const
{
+ DEBUG_ASSERT(Inside(v1_index, cl) != Inside(v2_index, cl));
// find the point of intersection from the given edge with a clip plane.
// the edge is the vertex with the same number and the one before it.
// Get pointers to the vertecies we will use
@@ -181,6 +182,8 @@
// t * (cl[0] * dx + cl[1] * dy) + cl[0] * v1_x + cl[1] * v1_y + cl[2] = 0
// t * (cl[0] * dx + cl[1] * dy) = -cl[0] * v1_x - cl[1] * v1_y - cl[2]
// so we get:
+ /* FIXME this assertion sometimes fails. t should always be between 0 and 1.
+ */
DEBUG_ASSERT(cl[0] * dx + cl[1] * dy);
double t = (-cl[0] * v1->tex_c[0] - cl[1] * v1->tex_c[1] - cl[2]) /
(cl[0] * dx + cl[1] * dy),
@@ -192,6 +195,7 @@
td1 = 1.0 - t,
xc = v1->vertex_c[0] * td1 + v2->vertex_c[0] * t,
yc = v1->vertex_c[1] * td1 + v2->vertex_c[1] * t;
+ DEBUG_ASSERT(0.0 <= t && t <= 1.0);
return Vertex(xc, yc, x, y);
}
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -19,8 +19,14 @@
*
*/
+#include <config.h>
+#include "panoinc_WX.h"
+#include "panoinc.h"
+
#include "PreviewDragTool.h"
#include "CommandHistory.h"
+#include "PT/PanoCommand.h"
+
#include <math.h>
#include <GL/gl.h>
@@ -47,13 +53,16 @@
// how far are we moving?
if (drag_yaw || drag_pitch)
{
+ /* TODO to the user, it would make more sense if the point they
+ * started dragging followed the mouse pointer. This doesn't work
+ * if the user drags from a point other than the centre. */
double yaw, pitch;
helper->GetViewStatePtr()->GetProjectionInfo()->ImageToAngular(yaw,
pitch, x, y);
- shift_coordinates.x = yaw - start_coordinates.x;
- shift_coordinates.y = start_coordinates.y - pitch;
- if (!drag_yaw) shift_coordinates.x = 0.0;
- if (!drag_pitch) shift_coordinates.y = 0.0;
+ shift_coordinates.x = yaw;
+ shift_coordinates.y = pitch;
+ if (!drag_yaw) shift_coordinates.x = start_coordinates.x;
+ if (!drag_pitch) shift_coordinates.y = start_coordinates.y;
}
if (drag_roll)
{
@@ -69,6 +78,7 @@
double new_yaw, new_pitch, new_roll;
i->second.Move(shift_coordinates.x, shift_coordinates.y,
shift_angle,
+ start_coordinates.x, start_coordinates.y, 0.0,
new_yaw, new_pitch, new_roll);
img.setYaw(new_yaw); img.setPitch(new_pitch); img.setRoll(new_roll);
helper->GetViewStatePtr()->SetSrcImage(i->first, &img);
@@ -125,21 +135,33 @@
hugin_utils::FDiff2D angular = helper->GetMousePosition() - centre;
start_angle = atan2(angular.y, angular.x);
shift_angle = 0.0;
+ // we'll always rotate around the centre of the panorama.
+ start_coordinates.x = 0.0; start_coordinates.y = 0.0;
+ shift_coordinates.x = 0.0; shift_coordinates.y = 0.0;
}
if (drag_yaw || drag_pitch)
{
+ // We want to keep the point under the mouse pointer now under there
+ // wherever it goes. We'll calculate the roll, pitch, and yaw
+ // required to bring the centre to the point under the mouse. Then
+ // we rotate the panorama's images using the yaw and pitch of the
+ // movement. (Rotate start point to the centre, rotate by difference
+ // in yaw and pitch gained so far while dragging, then do the
+ // inverse of the rotation from start point to the centre on the
+ // result.
// set angles
+ double yaw, pitch;
hugin_utils::FDiff2D mouse_pos = helper->GetMousePosition();
- double yaw, pitch;
helper->GetViewStatePtr()->GetProjectionInfo()->ImageToAngular(yaw,
pitch, mouse_pos.x, mouse_pos.y);
- start_coordinates.x = yaw;
- start_coordinates.y = pitch;
+ start_coordinates.x = yaw; start_coordinates.y = pitch;
+ shift_coordinates.x = yaw; shift_coordinates.y = pitch;
+ // find the base transformation
+ base_rot[0] = yaw; base_rot[1] = pitch; base_rot[2] = 0.0;
}
if (drag_roll || drag_yaw || drag_pitch)
{
shift_angle = 0.0;
- shift_coordinates.x = 0.0; shift_coordinates.y = 0.0;
// record where the images are so we know what the difference is.
// TODO use the topmost drawn component instead of all of the images
/*std::set<unsigned int> dragging_images
@@ -165,12 +187,18 @@
panorama.updateVariable( i, Variable("p", p) );
panorama.updateVariable( i, Variable("r", r) );
panorama.imageChanged(i);*/
- // TODO rotate the right stuff.
+ // TODO rotate the right stuff when not rotating the entire panorama.
+ // TODO use a single command, not two.
GlobalCmdHist::getInstance().addCommand(
new PT::RotatePanoCmd(*helper->GetPanoramaPtr(),
- shift_coordinates.x, shift_coordinates.y,
- shift_angle)
- );
+ -start_coordinates.x, start_coordinates.y,
+ -shift_angle),
+ true);
+ GlobalCmdHist::getInstance().addCommand(
+ new PT::RotatePanoCmd(*helper->GetPanoramaPtr(),
+ shift_coordinates.x, -shift_coordinates.y,
+ shift_angle),
+ true);
// stop dragging
image_angles.clear();
drag_yaw = false; drag_pitch = false; drag_roll = false;
@@ -216,18 +244,30 @@
void PreviewDragTool::AngleStore::Move(double yaw_shift, double pitch_shift,
double roll_shift,
+ double yaw_start, double pitch_start,
+ double roll_start,
double &yaw_out, double &pitch_out,
double &roll_out)
{
- // rotate the image around the centre point.
- Matrix3 transform_matrix, original_matrix, output_matrix;
- transform_matrix.SetRotationPT(DEG_TO_RAD(yaw_shift),
- DEG_TO_RAD(pitch_shift),
- DEG_TO_RAD(roll_shift));
+ // rotate the start point to the centre
+ Matrix3 base_rot_matrix, shift_rot_matrix, base_rot_inverse_matrix,
+ original_matrix, output_matrix;
original_matrix.SetRotationPT(DEG_TO_RAD(yaw),
DEG_TO_RAD(pitch),
DEG_TO_RAD(roll));
- output_matrix = transform_matrix * original_matrix;
+ base_rot_matrix.SetRotationPT(-DEG_TO_RAD(yaw_start),
+ DEG_TO_RAD(pitch_start),
+ -DEG_TO_RAD(roll_start));
+ shift_rot_matrix.SetRotationPT(DEG_TO_RAD(yaw_shift),
+ -DEG_TO_RAD(pitch_shift),
+ DEG_TO_RAD(roll_shift));
+ /*base_rot_inverse_matrix.SetRotationPT(-DEG_TO_RAD(yaw_start),
+ DEG_TO_RAD(pitch_start),
+ DEG_TO_RAD(roll_start));*/
+ output_matrix = /*base_rot_inverse_matrix **/ base_rot_matrix *
+ shift_rot_matrix * original_matrix;
+ //output_matrix = shift_rot_matrix * original_matrix;
+ // collect the resultant rotations
output_matrix.GetRotationPT(yaw_out, pitch_out, roll_out);
yaw_out = RAD_TO_DEG(yaw_out);
pitch_out = RAD_TO_DEG(pitch_out);
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewDragTool.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -60,14 +60,15 @@
double yaw, pitch, roll;
void Set(HuginBase::SrcPanoImage *img);
void Move(double yaw_shift, double pitch_shift, double roll_shift,
+ double yaw_start, double pitch_start, double roll_start,
double &yaw_out, double &pitch_out, double &roll_out);
};
private:
std::map<unsigned int, AngleStore> image_angles;
bool drag_yaw, drag_pitch, drag_roll;
double start_angle, shift_angle;
- hugin_utils::FDiff2D centre;
- hugin_utils::FDiff2D start_coordinates, shift_coordinates;
+ hugin_utils::FDiff2D centre, start_coordinates, shift_coordinates;
+ double base_rot[3];
bool shift, control, alt;
};
Added: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.cpp (rev 0)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -0,0 +1,356 @@
+// -*- c-basic-offset: 4 -*-
+/** @file PreviewIdentifyTool.cpp
+ *
+ * @author James Legg
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "PreviewIdentifyTool.h"
+#include <config.h>
+
+#include "panoinc_WX.h"
+
+#include "panoinc.h"
+
+#include "base_wx/platform.h"
+#include "GLPreviewFrame.h"
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include <algorithm>
+#include <vector>
+
+// the size of the rectangular texture. Must be a power of two, and at least 8.
+#define rect_ts 64
+// the number of times larger the circular texture is, must be a power of 2, and
+// at least 1. Making better improves the appearance of the circle.
+#define circle_ts_multiple 4
+#define circle_ts (rect_ts * circle_ts_multiple)
+#define circle_middle ((float) (circle_ts - 1) / 2.0)
+#define circle_border_outer (circle_middle - 0.5 * (float) circle_ts_multiple)
+#define circle_border_inner (circle_middle - 2.5 * (float) circle_ts_multiple)
+#define circle_border_peak (circle_middle - 1.5 * (float) circle_ts_multiple)
+
+PreviewIdentifyTool::PreviewIdentifyTool(PreviewToolHelper *helper,
+ GLPreviewFrame *owner)
+ : PreviewTool(helper)
+{
+ preview_frame = owner;
+ // make the textures. We have a circle border and a square one.
+ // the textures are white with a the alpha chanel forming a border.
+ glGenTextures(1, &rectangle_border_tex);
+ glGenTextures(1, &circle_border_tex);
+ // we only want to specify alpha, but using just alpha in opengl attaches 0
+ // for the luminosity. We'll bias rgb values to get 1.0, so we can colour
+ // the texture in something other than black:
+ glPixelTransferf(GL_RED_BIAS, 1.0);
+ glPixelTransferf(GL_GREEN_BIAS, 1.0);
+ glPixelTransferf(GL_BLUE_BIAS, 1.0);
+ {
+ // In the rectangle texture, the middle is 1/4 opaque, the outer pixels
+ // are completely transparent, and one pixel in from the edges is
+ // a completly opaque line.
+ unsigned char rect_tex_data[rect_ts][rect_ts];
+ for (unsigned int x = 2; x < rect_ts-2; x++)
+ {
+ for (unsigned int y = 2; y < rect_ts - 2; y++)
+ {
+ rect_tex_data[x][y] = 63;
+ }
+ }
+ for (unsigned int d = 1; d < rect_ts - 1; d++)
+ {
+ rect_tex_data[d][1] = 255;
+ rect_tex_data[d][rect_ts - 2] = 255;
+ rect_tex_data[1][d] = 255;
+ rect_tex_data[rect_ts - 2][d] = 255;
+ }
+ for (unsigned int d = 0; d < rect_ts; d++)
+ {
+ rect_tex_data[d][0] = 0;
+ rect_tex_data[d][rect_ts - 1] = 0;
+ rect_tex_data[0][d] = 0;
+ rect_tex_data[rect_ts - 1][d] = 0;
+ }
+ glBindTexture(GL_TEXTURE_2D, rectangle_border_tex);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, rect_ts, rect_ts,
+ GL_ALPHA, GL_UNSIGNED_BYTE, rect_tex_data);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ }
+ {
+ // the circular one should look similar to the rectangle one, but we
+ // enlarge it so that the circle apears less blocky. We don't want to
+ // make it equally sharper however, so we make it a bit fuzzier by
+ // blending.
+ unsigned char circle_tex_data[circle_ts][circle_ts];
+ for (unsigned int x = 0; x < circle_ts; x++)
+ {
+ for (unsigned int y = 0; y < circle_ts; y++)
+ {
+ float x_offs = (float) x - circle_middle,
+ y_offs = (float) y - circle_middle,
+ radius = sqrt(x_offs * x_offs + y_offs * y_offs),
+ intensity;
+ if (radius < circle_border_inner)
+ {
+ intensity = 63.0;
+ } else if (radius < circle_border_peak)
+ {
+ intensity = (radius - circle_border_inner) /
+ (float) circle_ts_multiple * 255.0 * 3.0 / 4.0 + 64.0;
+ } else if (radius < circle_border_outer)
+ {
+ intensity = (radius - circle_border_peak) /
+ (float) circle_ts_multiple * -255.0 + 256.0;
+ } else
+ {
+ intensity = 0.0;
+ }
+ circle_tex_data[x][y] = (unsigned char) intensity;
+ }
+ }
+ glBindTexture(GL_TEXTURE_2D, circle_border_tex);
+ gluBuild2DMipmaps(GL_TEXTURE_2D,
+ GL_LUMINANCE_ALPHA, circle_ts, circle_ts,
+ GL_ALPHA, GL_UNSIGNED_BYTE, circle_tex_data);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+ }
+ // set these back as expected.
+ glPixelTransferf(GL_RED_BIAS, 0.0);
+ glPixelTransferf(GL_GREEN_BIAS, 0.0);
+ glPixelTransferf(GL_BLUE_BIAS, 0.0);
+}
+PreviewIdentifyTool::~PreviewIdentifyTool()
+{
+ // free the textures
+ glDeleteTextures(1, &rectangle_border_tex);
+ glDeleteTextures(1, &circle_border_tex);
+}
+
+void PreviewIdentifyTool::Activate()
+{
+ // register notifications
+ helper->NotifyMe(PreviewToolHelper::MOUSE_MOVE, this);
+ helper->NotifyMe(PreviewToolHelper::DRAW_OVER_IMAGES, this);
+ helper->NotifyMe(PreviewToolHelper::IMAGES_UNDER_MOUSE_CHANGE, this);
+
+ // clear up
+ // Assume that there are no images under the mouse when the tool is
+ // activated. This should be fine if the user clicks the button to activate
+ // the tool.
+ image_set.clear();
+ /* TODO if it becomes possible to activate the tool by a keyboard shortcut
+ * or something, call ImagesUnderMouseChangedEvent() to make sure we display
+ * indicators for images currently under the cursor. */
+}
+
+void PreviewIdentifyTool::ImagesUnderMouseChangedEvent()
+{
+ // If we are currently showing indicators for some of the images, we want
+ // to work out which ones are not in the new set, so we can set their
+ // buttons back to the system colour.
+ std::set<unsigned int> new_image_set = helper->GetImageNumbersUnderMouse();
+ std::vector<unsigned int> difference(image_set.size());
+ std::vector<unsigned int>::iterator end;
+ end = std::set_difference (image_set.begin(), image_set.end(),
+ new_image_set.begin(), new_image_set.end(),
+ difference.begin());
+ DEBUG_ASSERT(end >= difference.begin() && end <= difference.end());
+ std::vector<unsigned int>::iterator iterator;
+ if (iterator != end)
+ {
+ for (iterator = difference.begin(); iterator < end; iterator++)
+ {
+ DEBUG_ASSERT(*iterator < helper->GetPanoramaPtr()->getNrOfImages());
+ // reset this button to its default system colour.
+ preview_frame->SetImageButtonColour(*iterator, 0, 0, 0);
+ // remove the notification
+ helper->DoNotNotifyMeBeforeDrawing(*iterator, this);
+ }
+ }
+ image_set.swap(new_image_set);
+
+ // Redraw with new indicators. Since the indicators aren't part of the
+ // panorama and none of it is likely to change, we have to persuade the
+ // viewstate that a redraw is required.
+ helper->GetViewStatePtr()->ForceRequireRedraw();
+ helper->GetViewStatePtr()->Redraw();
+}
+
+void PreviewIdentifyTool::AfterDrawImagesEvent()
+{
+ // we draw the partly transparent identification boxes over the top of the
+ // entire stack of images in image_set so that the extents of images in the
+ // background are clearly marked.
+ unsigned int num_images = image_set.size();
+ // draw the actual images
+ std::set<unsigned int>::iterator it;
+ for (it = image_set.begin(); it != image_set.end(); it++)
+ {
+ DEBUG_ASSERT(*it < helper->GetPanoramaPtr()->getNrOfImages());
+ helper->GetViewStatePtr()->GetTextureManager()->
+ DrawImage(*it,
+ helper->GetViewStatePtr()->GetMeshDisplayList(*it));
+ }
+ // now draw the identification boxes
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glMatrixMode(GL_TEXTURE);
+ unsigned int image_counter = 0;
+ for (it = image_set.begin(); it != image_set.end(); it++)
+ {
+ // we want to shift the texture so it lines up with the cropped region.
+ glPushMatrix();
+ HuginBase::SrcPanoImage *src = helper->GetViewStatePtr()->
+ GetSrcImage(*it);
+ int width = src->getSize().width(), height = src->getSize().height();
+ vigra::Rect2D crop_region = src->getCropRect();
+ // pick a texture depending on crop mode and move it to the cropped area
+ switch (src->getCropMode())
+ {
+ case HuginBase::SrcPanoImage::CROP_CIRCLE:
+ glBindTexture(GL_TEXTURE_2D, circle_border_tex);
+ // change the crop region to a square around the circle.
+ if (crop_region.width() < crop_region.height())
+ {
+ // too tall, move top and bottom.
+ int diff = (crop_region.width() - crop_region.height()) / 2;
+ // diff is negative, so we will shrink the border in the y
+ // direction.
+ crop_region.addBorder(0, diff);
+ } else if (crop_region.width() > crop_region.height())
+ {
+ // too wide, move left and right
+ int diff = (crop_region.height() - crop_region.width()) / 2;
+ crop_region.addBorder(diff, 0);
+ }
+ {
+ float diameter = (float) crop_region.width();
+ glScalef((float) width / diameter,
+ (float) height / diameter, 1.0);
+ glTranslatef(-(float) crop_region.left() / (float) width,
+ -(float) crop_region.top() / (float) height,
+ 0.0);
+ }
+ break;
+ case HuginBase::SrcPanoImage::CROP_RECTANGLE:
+ // get the biggest rectangle contained by both the image
+ // and the cropped area.
+ crop_region &= vigra::Rect2D(src->getSize());
+ glBindTexture(GL_TEXTURE_2D, rectangle_border_tex);
+ glScalef((float) width / (float) crop_region.width(),
+ (float) height / (float) crop_region.height(),
+ 1.0);
+ glTranslatef(-(float) crop_region.left() / (float) width,
+ -(float) crop_region.top() / (float) height,
+ 0.0);
+ break;
+ case HuginBase::SrcPanoImage::NO_CROP:
+ glBindTexture(GL_TEXTURE_2D, rectangle_border_tex);
+ break;
+ }
+ // draw the image in this texture
+ unsigned char r,g,b;
+ HighlightColour(image_counter, num_images, r, g, b);
+ image_counter++;
+ glColor3ub(r,g,b);
+ glCallList(helper->GetViewStatePtr()->GetMeshDisplayList(*it));
+ glPopMatrix();
+ // tell the preview frame to update the button to show the same colour.
+ preview_frame->SetImageButtonColour(*it, r, g, b);
+ }
+ // set stuff back how we found it.
+ glMatrixMode(GL_MODELVIEW);
+ glDisable(GL_BLEND);
+ glColor3ub(255, 255, 255);
+}
+
+bool PreviewIdentifyTool::BeforeDrawImageNumber(unsigned int image)
+{
+ // Delay drawing of images, so we can show them on top of the others.
+ DEBUG_ASSERT(image < helper->GetPanoramaPtr()->getNrOfImages());
+ if (image_set.count(image)) return false;
+ return true;
+}
+
+void PreviewIdentifyTool::ShowImageNumber(unsigned int image)
+{
+ DEBUG_ASSERT(image < helper->GetPanoramaPtr()->getNrOfImages());
+ // Add this image to the set of images drawn.
+ image_set.insert(image);
+ // now we want a redraw.
+ helper->GetViewStatePtr()->ForceRequireRedraw();
+ helper->GetViewStatePtr()->Redraw();
+}
+
+void PreviewIdentifyTool::StopShowingImages()
+{
+ // set the colour to the image the user just moused off to the default.
+ preview_frame->SetImageButtonColour(*image_set.begin(), 0, 0, 0);
+ image_set.clear();
+ // now redraw without the indicator.
+ helper->GetViewStatePtr()->ForceRequireRedraw();
+ helper->GetViewStatePtr()->Redraw();
+}
+
+// generate a colour given how many colours we need and an index.
+void PreviewIdentifyTool::HighlightColour(unsigned int index,
+ unsigned int count,
+ unsigned char &red,
+ unsigned char &green,
+ unsigned char &blue)
+{
+ DEBUG_ASSERT(index < count && index >= 0);
+ // the first one is red, the rest are evenly spaced throughout the spectrum
+ float hue = ((float) index / (float) count) * 6.0;
+ if (hue < 1.0)
+ {
+ // red to yellow
+ red = 255;
+ green = (unsigned char) (hue * 255.0);
+ blue = 0;
+ } else if (hue < 2.0) {
+ // yellow to green
+ red = (unsigned char) ((-hue + 2.0) * 255.0);
+ green = 255;
+ blue = 0;
+ } else if (hue < 3.0) {
+ // green to cyan
+ red = 0;
+ green = 255;
+ blue = (unsigned char) ((hue - 2.0) * 255.0);
+ } else if (hue < 4.0) {
+ // cyan to blue
+ red = 0;
+ green = (unsigned char) ((-hue + 4.0) * 255.0);
+ blue = 255;
+ } else if (hue < 5.0) {
+ // blue to magenta
+ red = (unsigned char) ((hue - 4.0) * 255.0);
+ green = 0;
+ blue = 255;
+ } else {
+ // magenta to red
+ red = 255;
+ green = 0;
+ blue = (unsigned char) ((-hue + 6.0) * 255.0);
+ }
+}
+
Added: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.h (rev 0)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewIdentifyTool.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -0,0 +1,65 @@
+// -*- c-basic-offset: 4 -*-
+/** @file PreviewIdentifyTool.cpp
+ *
+ * @author James Legg
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* The PreviewIdentifyTool connects the image numbers with the image on the
+ * preview. There are two ways it does this:
+ * 1. When the user moves the mouse pointer over a image button, the image is
+ * highlighted in the preview.
+ * 2. When the user moves the mouse pointer over the preview, the image under
+ * the pointer are highlighted with matching colours over the buttons.
+ * The "highlighted" images are drawn on top of the other images, with a
+ * coloured border.
+ */
+
+#ifndef _PREVIEWIDENTIFYTOOL_H
+#define _PREVIEWIDENTIFYTOOL_H
+
+#include "PreviewTool.h"
+#include <set>
+
+class GLPreviewFrame;
+
+class PreviewIdentifyTool : public PreviewTool
+{
+public:
+ PreviewIdentifyTool(PreviewToolHelper *helper, GLPreviewFrame *owner);
+ ~PreviewIdentifyTool();
+ void Activate();
+ void ImagesUnderMouseChangedEvent();
+ void AfterDrawImagesEvent();
+ bool BeforeDrawImageNumber(unsigned int image);
+ // these are called when the user moves the mouse over the image buttons.
+ void ShowImageNumber(unsigned int image); // mouse on
+ void StopShowingImages(); // mouse off
+private:
+ // generate a colour given how many colours we need and an index.
+ void HighlightColour(unsigned int index, unsigned int count,
+ unsigned char &red, unsigned char &green,
+ unsigned char &blue);
+ // the OpenGL texture name for the two borders:
+ unsigned int circle_border_tex, rectangle_border_tex;
+ // the set of image numbers of the images we are displaying.
+ std::set<unsigned int> image_set;
+ GLPreviewFrame *preview_frame;
+};
+
+#endif
+
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewTool.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewTool.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewTool.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -41,13 +41,16 @@
/* When the user switches on the tool, Activate is called. We should
* register events we want to respond to with the helper when activating,
- * these are lost when the tool is deactivated, but we are not notified. */
+ * these are lost when the tool is deactivated, but we are not notified of
+ * this. Activate will be called again if the tool is reactivated, we should
+ * clean up anything we need to from the previous use here. */
virtual void Activate() = 0;
// These are called when events happen, providing we requested notification.
// The coordinates are in the space of the panorama output at full size.
virtual void MouseMoveEvent(double x, double y) {}
virtual void MouseButtonEvent(wxMouseEvent &e) {}
+ virtual void ImagesUnderMouseChangedEvent() {}
virtual void KeypressEvent(int keycode, int modifiers, bool pressed) {}
// In the next few events we are free to draw stuff in OpenGL.
virtual void BeforeDrawImagesEvent() {}
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -24,6 +24,7 @@
#include "PreviewToolHelper.h"
#include "PreviewTool.h"
+
PreviewToolHelper::PreviewToolHelper(PT::Panorama *pano_in,
ViewState *view_state_in)
{
@@ -72,7 +73,31 @@
(*iterator)->MouseMoveEvent(mouse_x, mouse_y);
}
// If the mouse has moved, then we don't know what is underneath it anoymore
+ InvalidateImagesUnderMouse();
+}
+
+void PreviewToolHelper::InvalidateImagesUnderMouse()
+{
images_under_mouse_current = false;
+ // if there are tools that want to know when the images under the mouse
+ // pointer change, we better detect the images and notfiy them is applicable
+ if (!images_under_mouse_notified_tools.empty())
+ {
+ // there are tools that want to know... so find out:
+ std::set<unsigned int> old_images_under_mouse = images_under_mouse;
+ UpdateImagesUnderMouse();
+ if (old_images_under_mouse != images_under_mouse)
+ {
+ // The list has changed. Notifiy all tools that requested it.
+ std::set<PreviewTool *>::iterator iterator;
+ for (iterator = images_under_mouse_notified_tools.begin();
+ iterator != images_under_mouse_notified_tools.end();
+ iterator++)
+ {
+ (*iterator)->ImagesUnderMouseChangedEvent();
+ }
+ }
+ }
}
void PreviewToolHelper::MouseButtonEvent(wxMouseEvent &e)
@@ -102,7 +127,7 @@
(*iterator)->BeforeDrawImagesEvent();
}
// Since we are drawing a new frame, lets assume something has changed.
- images_under_mouse_current = false;
+ InvalidateImagesUnderMouse();
}
void PreviewToolHelper::AfterDrawImages()
@@ -182,6 +207,9 @@
case DRAW_OVER_IMAGES:
AddTool(tool, &draw_over_notified_tools);
break;
+ case IMAGES_UNDER_MOUSE_CHANGE:
+ AddTool(tool, &images_under_mouse_notified_tools);
+ break;
}
}
@@ -218,6 +246,9 @@
case DRAW_OVER_IMAGES:
RemoveTool(tool, &draw_over_notified_tools);
break;
+ case IMAGES_UNDER_MOUSE_CHANGE:
+ RemoveTool(tool, &images_under_mouse_notified_tools);
+ break;
}
}
@@ -272,9 +303,12 @@
std::vector<PreviewTool *> *vector,
unsigned int index)
{
- if ((*vector)[index] == tool)
+ if ((*vector).size() > index)
{
- (*vector)[index] = 0;
+ if ((*vector)[index] == tool)
+ {
+ (*vector)[index] = 0;
+ }
}
}
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/PreviewToolHelper.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -24,6 +24,7 @@
* and guides the interaction between tools. These features are available:
* - Notification of user events:
* - When the mouse moves
+ * - When the set of images under the mouse pointer changes
* - When the mouse button is pressed / released.
* - When a key is pressed / released
* - Notifications when drawing things on the preview, allowing:
@@ -32,10 +33,6 @@
* - Replacing or stopping the drawing of each individual image.
* - Notification of when:
* - The tool is activated.
- * - The tool is deactivated.
- * - The tool has to give up some event notifications.
- * (when another tool requests them, we don't want two different things
- * responding to the same mouse click for example)
* - The tool can request the mouse position.
* - The tool can request a list of images under the mouse.
* - The tool can access the panorama, and make changes to it.
@@ -58,7 +55,7 @@
#include <hugin_math/hugin_math.h>
#include "ViewState.h"
-#include "panoinc.h"
+#include "PT/Panorama.h"
class PreviewTool;
@@ -69,6 +66,7 @@
{
MOUSE_MOVE, MOUSE_PRESS, KEY_PRESS,
DRAW_UNDER_IMAGES, DRAW_OVER_IMAGES,
+ IMAGES_UNDER_MOUSE_CHANGE
};
PreviewToolHelper(PT::Panorama *pano,
ViewState *view_state);
@@ -118,6 +116,7 @@
PreviewTool * keypress_notified_tool;
std::set<PreviewTool *> draw_under_notified_tools;
std::set<PreviewTool *> draw_over_notified_tools;
+ std::set<PreviewTool *> images_under_mouse_notified_tools;
// these are vectors: the index is the image that a single tool uses.
std::vector<PreviewTool *> image_draw_begin_tools;
std::vector<PreviewTool *> image_draw_end_tools;
@@ -132,10 +131,13 @@
void AddTool(PreviewTool *tool, std::set<PreviewTool *> *set);
void AddTool(PreviewTool *tool, std::vector<PreviewTool *> *vector,
unsigned int index);
+
// is the set of images under the mouse up to date?
bool images_under_mouse_current;
+ // which images are under the mouse?
std::set<unsigned int> images_under_mouse;
void UpdateImagesUnderMouse();
+ void InvalidateImagesUnderMouse();
};
#endif
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -23,10 +23,11 @@
#include "TexCoordRemapper.h"
#include "algorithms/nona/ComputeImageROI.h"
#include "ViewState.h"
-#include <cstdlib>
// higher values make the mesh more detailed, but slower and using more memory:
-const double mesh_frequency = 0.0884;
+// Value is in faces per pixel in each direction, so it should be positive and
+// less than 1. Faces will be around this size, approximately square.
+const double mesh_frequency = 0.07;
TexCoordRemapper::TexCoordRemapper(HuginBase::Panorama *m_pano,
unsigned int image_number,
@@ -50,13 +51,13 @@
{
for (unsigned int y = 0; y < divisions_y; y++)
{
- transform.transformImgCoord(map[x][y].first,
- map[x][y].second,
+ transform.transformImgCoord(map[x][y].x,
+ map[x][y].y,
(double) x * face_width + start_x,
(double) y * face_height + start_y);
// texture coordinates on the image range from 0 to 1.
- map[x][y].first /= width;
- map[x][y].second /= height;
+ map[x][y].x /= width;
+ map[x][y].y /= height;
}
}
face_index = 0;
@@ -82,10 +83,10 @@
for (unsigned short int y = 0; y < 2; y++)
{
unsigned int xt = x_f + x, yt = y_f + y;
- if (map[xt][yt].first > crop_x1) all_left = false;
- if (map[xt][yt].first < crop_x2) all_right = false;
- if (map[xt][yt].second > crop_y1) all_above = false;
- if (map[xt][yt].second < crop_y2) all_below = false;
+ if (map[xt][yt].x > crop_x1) all_left = false;
+ if (map[xt][yt].x < crop_x2) all_right = false;
+ if (map[xt][yt].y > crop_y1) all_above = false;
+ if (map[xt][yt].y < crop_y2) all_below = false;
}
}
/* check if this quad shows any of the input image.
@@ -103,8 +104,8 @@
for (unsigned short int y = 0; y < 2; y++)
{
unsigned int xt = x_f + x, yt = y_f + y;
- result->tex_c[x][y][0] = map[xt][yt].first;
- result->tex_c[x][y][1] = map[xt][yt].second;
+ result->tex_c[x][y][0] = map[xt][yt].x;
+ result->tex_c[x][y][1] = map[xt][yt].y;
result->vertex_c[x][y][0] = (double) xt * face_width + start_x;
result->vertex_c[x][y][1] = (double) yt * face_height + start_y;
}
@@ -126,6 +127,9 @@
int(result->tex_c[1][1][1] * height))))
{
// all inside, doesn't need clipping.
+ /* FIXME Alber's equal area conic projection needs to be clipped to the
+ * sides space in the output that maps to the panorama...
+ */
return true;
}
/* We have to clip the face to the source image. This may produce many faces
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TexCoordRemapper.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -32,6 +32,8 @@
#define __TEXCOORDREMAPPER_H
#include "MeshRemapper.h"
+#include <vector>
+#include "hugin_math/hugin_math.h"
class TexCoordRemapper: public MeshRemapper
{
@@ -44,7 +46,7 @@
void SetSize();
// this stores all the coordinates, and can return rows of them.
// arrays don't meet the requirements for std::vector, so we use a pair.
- std::vector< std::vector< std::pair<double, double> > > map;
+ std::vector< std::vector<hugin_utils::FDiff2D> > map;
// dimensions for the area we cover. This can be used for clipping.
double start_x, start_y, end_x, end_y;
// this is the number of vertices we use in each direction.
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -34,8 +34,8 @@
#include <GL/glu.h>
#include <config.h>
-#include "panoinc_WX.h"
-#include "panoinc.h"
+//#include "panoinc_WX.h"
+//#include "panoinc.h"
#include "ViewState.h"
#include "TextureManager.h"
@@ -43,14 +43,13 @@
#include "vigra/stdimage.hxx"
#include "vigra/resizeimage.hxx"
#include "vigra/impex.hxx"
-#include <vigra_ext/Pyramid.h>
+//#include <vigra_ext/Pyramid.h>
#include "base_wx/ImageCache.h"
-#include "photometric/ResponseTransform.h"
+#include "photometric/ResponseTransform.h"
-
-TextureManager::TextureManager(PT::Panorama &pano, ViewState *view_state_in)
+TextureManager::TextureManager(PT::Panorama *pano, ViewState *view_state_in)
{
- m_pano = &pano;
+ m_pano = pano;
photometric_correct = false;
view_state = view_state_in;
}
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/TextureManager.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -40,6 +40,7 @@
#include <string>
#include <map>
+#include "PT/Panorama.h"
class GLViewer;
class ViewState;
@@ -47,7 +48,7 @@
class TextureManager
{
public:
- TextureManager(PT::Panorama &pano, ViewState *view);
+ TextureManager(PT::Panorama *pano, ViewState *view);
virtual ~TextureManager();
// selct the texture for the requested image in opengl
void DrawImage(unsigned int image_number, unsigned int display_list);
@@ -57,8 +58,10 @@
// change the OpenGL state for rendering the textures.
void Begin();
void End();
- // set to true if we aer doing photmetric correction
+ // set to true if we are doing photmetric correction
void SetPhotometricCorrect(bool state);
+ // return true if we are doing photometric correction.
+ bool GetPhotometricCorrect() {return photometric_correct;}
protected:
PT::Panorama * m_pano;
ViewState *view_state;
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/VertexCoordRemapper.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/VertexCoordRemapper.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/VertexCoordRemapper.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -75,10 +75,10 @@
// this is the length in screen pixels under which no subdivision occurs.
// higher values are faster, lower ones more accurate.
// TODO user preference? Increase during interactive changes?
-const double min_length = 4.0;
+const double min_length = 14.0;
// the angle in radians under which no subdivision occurs. Again, higher values
// will make it faster, lower ones will give higher accuracy. must be positive.
-const double min_angle = 0.05;
+const double min_angle = 0.06;
// the distance in absolute screen pixels between twice the length of the
// children and the length of the parent nodes, under which no subdivision
// occurs. higher values are faster, lower values give higher accuracy. Must be
@@ -1110,6 +1110,9 @@
// if any of the vertices we are want to use are invalid (e.g. behind the
// viewer in a rectilinear projection) we don't want to risk using them:
if (nodes[node_id].flags & (transform_fail_flag * 15)) return 0;
+ // if this face crosses a discontinuity, we should be using a point off
+ // screen instead of in the middle. Refuse to use these faces
+ if (nodes[node_id].flags & (vertex_side_flag_start * 15)) return 0;
// linearly interpolate the node's corners.
// most of the time we only use factors of 0 and 1, we don't want to make
// points up except when trying to connect a point on a highly subdivided
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.cpp
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.cpp 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.cpp 2008-08-01 03:43:35 UTC (rev 3258)
@@ -21,8 +21,9 @@
*/
#include "ViewState.h"
+#include "MeshManager.h"
-ViewState::ViewState(HuginBase::Panorama *pano,
+ViewState::ViewState(PT::Panorama *pano,
void (*RefreshFunction)(void *), void * arg)
{
m_pano = pano;
@@ -43,12 +44,18 @@
opts = m_pano->getOptions();
projection_info = new OutputProjectionInfo(&opts);
genscale = 0.0;
+ // now set the texture manager up.
+ m_tex_manager = new TextureManager(m_pano, this);
+ // same for the mesh manager
+ m_mesh_manager = new MeshManager(m_pano, this);
}
ViewState::~ViewState()
{
m_pano->removeObserver(this);
delete projection_info;
+ delete m_tex_manager;
+ delete m_mesh_manager;
}
float ViewState::GetScale()
@@ -312,3 +319,14 @@
dirty_photometrics = false;
}
+void ViewState::DoUpdates()
+{
+ m_tex_manager->CheckUpdate();
+ m_mesh_manager->CheckUpdate();
+}
+
+unsigned int ViewState::GetMeshDisplayList(unsigned int image_number)
+{
+ return m_mesh_manager->GetDisplayList(image_number);
+}
+
Modified: hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.h
===================================================================
--- hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.h 2008-07-31 21:25:05 UTC (rev 3257)
+++ hugin/branches/gsoc2008_opengl_preview/src/hugin1/hugin/ViewState.h 2008-08-01 03:43:35 UTC (rev 3258)
@@ -51,14 +51,17 @@
#include <panodata/PanoramaData.h>
#include <panodata/Panorama.h>
+#include "PT/Panorama.h"
#include "OutputProjectionInfo.h"
#include <vigra/diff2d.hxx>
+#include "TextureManager.h"
+#include "MeshManager.h"
class ViewState : public HuginBase::PanoramaObserver
{
public:
// constructor: we need to know what panorama we deal with.
- ViewState(HuginBase::Panorama *pano, void (*RefreshFunction)(void *), void *arg);
+ ViewState(PT::Panorama *pano, void (*RefreshFunction)(void *), void *arg);
~ViewState();
// the scale is the number of screen pixels per panorama pixel.
float GetScale();
@@ -82,6 +85,11 @@
OutputProjectionInfo *GetProjectionInfo();
HuginBase::SrcPanoImage *GetSrcImage(unsigned int image_nr);
+ // stuff used directly for drawing the preview, made accessible for tools.
+ unsigned int GetMeshDisplayList(unsigned int image_nr);
+ MeshManager * GetMeshManager() {return m_mesh_manager;}
+ TextureManager * GetTextureManager() {return m_tex_manager;}
+
// These functions are used to identify what needs to be redone on the next
// redraw.
// return true if we need to recalculate the mesh
@@ -119,8 +127,10 @@
// redraw the preview, but only if something has changed.
void Redraw();
+ // update the meshes and textures as necessary before drawing.
+ void DoUpdates();
protected:
- HuginBase::Panorama *m_pano;
+ PT::Panorama *m_pano;
float scale, genscale;
vigra::Rect2D visible_area;
void (*RefreshFunc)(void *);
@@ -147,6 +157,11 @@
// reset all the dirty flags.
void Clean();
+
+ // this stores all the textures we need.
+ TextureManager *m_tex_manager;
+ // this stores all the meshes we need.
+ MeshManager *m_mesh_manager;
};
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|