forked from Kitware/VTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vtkInteractorStyleUnicam.h
191 lines (162 loc) · 7.22 KB
/
vtkInteractorStyleUnicam.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*=========================================================================
Program: Visualization Toolkit
Module: vtkInteractorStyleUnicam.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*
* This work (vtkInteractorStyleUnicam.h) was produced under a grant from
* the Department of Energy to Brown University. Neither Brown University
* nor the authors assert any copyright with respect to this work and it may
* be used, reproduced, and distributed without permission.
*/
/**
* @class vtkInteractorStyleUnicam
* @brief provides Unicam navigation style
*
* UniCam is a camera interactor. Here, just the primary features of the
* UniCam technique are implemented. UniCam requires just one mouse button
* and supports context sensitive dollying, panning, and rotation. (In this
* implementation, it uses the right mouse button, leaving the middle and
* left available for other functions.) For more information, see the paper
* at:
*
* ftp://ftp.cs.brown.edu/pub/papers/graphics/research/unicam.pdf
*
* The following is a brief description of the UniCam Camera Controls. You
* can perform 3 operations on the camera: rotate, pan, and dolly the camera.
* All operations are reached through the right mouse button & mouse
* movements.
*
* IMPORTANT: UniCam assumes there is an axis that makes sense as a "up"
* vector for the world. By default, this axis is defined to be the
* vector <0,0,1>. You can set it explicitly for the data you are
* viewing with the 'SetWorldUpVector(..)' method in C++, or similarly
* in Tcl/Tk (or other interpreted languages).
*
* 1. ROTATE:
*
* Position the cursor over the point you wish to rotate around and press and
* release the left mouse button. A 'focus dot' appears indicating the
* point that will be the center of rotation. To rotate, press and hold the
* left mouse button and drag the mouse.. release the button to complete the
* rotation.
*
* Rotations can be done without placing a focus dot first by moving the
* mouse cursor to within 10% of the window border & pressing and holding the
* left button followed by dragging the mouse. The last focus dot position
* will be re-used.
*
* 2. PAN:
*
* Click and hold the left mouse button, and initially move the mouse left
* or right. The point under the initial pick will pick correlate w/ the
* mouse tip-- (i.e., direct manipulation).
*
* 3. DOLLY (+ PAN):
*
* Click and hold the left mouse button, and initially move the mouse up or
* down. Moving the mouse down will dolly towards the picked point, and moving
* the mouse up will dolly away from it. Dollying occurs relative to the
* picked point which simplifies the task of dollying towards a region of
* interest. Left and right mouse movements will pan the camera left and right.
*
* @warning
* (NOTE: This implementation of Unicam assumes a perspective camera. It
* could be modified relatively easily to also support an orthographic
* projection.)
*/
#ifndef vtkInteractorStyleUnicam_h
#define vtkInteractorStyleUnicam_h
#include "vtkInteractionStyleModule.h" // For export macro
#include "vtkInteractorStyle.h"
class vtkCamera;
class vtkWorldPointPicker;
//
// XXX - would have preferred to make these enumerations within the class,
// enum { NONE=0, BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT };
// enum {CAM_INT_ROT, CAM_INT_CHOOSE, CAM_INT_PAN, CAM_INT_DOLLY};
// but vtkWrapTcl signaled a "syntax error" when it parsed the 'enum' line.
// So, am making them defines which is what the other classes that want
// to have constants appear to do.
//
// buttons pressed
#define VTK_UNICAM_NONE 0
#define VTK_UNICAM_BUTTON_LEFT 1
#define VTK_UNICAM_BUTTON_MIDDLE 2
#define VTK_UNICAM_BUTTON_RIGHT 3
//
// camera modes
#define VTK_UNICAM_CAM_INT_ROT 0
#define VTK_UNICAM_CAM_INT_CHOOSE 1
#define VTK_UNICAM_CAM_INT_PAN 2
#define VTK_UNICAM_CAM_INT_DOLLY 3
class VTKINTERACTIONSTYLE_EXPORT vtkInteractorStyleUnicam : public vtkInteractorStyle
{
public:
static vtkInteractorStyleUnicam *New();
vtkTypeMacro(vtkInteractorStyleUnicam,vtkInteractorStyle);
void PrintSelf(ostream& os, vtkIndent indent) override;
void SetWorldUpVector(double a[3]) {this->SetWorldUpVector(a[0],a[1],a[2]);}
void SetWorldUpVector(double x, double y, double z);
vtkGetVectorMacro(WorldUpVector, double, 3);
//@{
/**
* Concrete implementation of event bindings
*/
void OnMouseMove() override;
void OnLeftButtonDown() override;
void OnLeftButtonUp() override;
virtual void OnLeftButtonMove();
//@}
/**
* OnTimer calls RotateCamera, RotateActor etc which should be overridden by
* style subclasses.
*/
void OnTimer() override;
protected:
vtkInteractorStyleUnicam();
~vtkInteractorStyleUnicam() override;
vtkWorldPointPicker *InteractionPicker;
int ButtonDown; // which button is down
double DTime; // time mouse button was pressed
double Dist; // distance the mouse has moved since button press
double StartPix[2]; // pixel mouse movement started at
double LastPos[2]; // normalized position of mouse last frame
double LastPix[2]; // pixel position of mouse last frame
double DownPt[3]; // 3D point under cursor when mouse button pressed
double Center [3]; // center of camera rotation
double WorldUpVector[3]; // what the world thinks the 'up' vector is
vtkActor *FocusSphere; // geometry for indicating center of rotation
int IsDot; // flag-- is the FocusSphere being displayed?
vtkRenderer *FocusSphereRenderer; // renderer for 'FocusSphere'
int state; // which navigation mode was selected?
void ChooseXY( int X, int Y ); // method for choosing type of navigation
void RotateXY( int X, int Y ); // method for rotating
void DollyXY( int X, int Y ); // method for dollying
void PanXY( int X, int Y ); // method for panning
// conveinence methods for translating & rotating the camera
void MyTranslateCamera(double v[3]);
void MyRotateCamera(double cx, double cy, double cz,
double ax, double ay, double az,
double angle);
// Given a 3D point & a vtkCamera, compute the vectors that extend
// from the projection of the center of projection to the center of
// the right-edge and the center of the top-edge onto the plane
// containing the 3D point & with normal parallel to the camera's
// projection plane.
void GetRightVandUpV(double *p, vtkCamera *cam,
double *rightV, double *upV);
// takes in pixels, returns normalized window coordinates
void NormalizeMouseXY(int X, int Y, double *NX, double *NY);
// return the aspect ratio of the current window
double WindowAspect();
private:
vtkInteractorStyleUnicam(const vtkInteractorStyleUnicam&) = delete;
void operator=(const vtkInteractorStyleUnicam&) = delete;
};
#endif // vtkInteractorStyleUnicam_h