61 #include "GLTrackball.hh"
74 GLTrackball(GLState& _state)
77 last_point_ok_(false),
80 for (
int i=0; i<10; ++i)
81 button_down_[i] =
false;
89 GLTrackball::mouse_press(
int button,
int x,
int y)
92 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
94 button_down_[button] =
true;
102 GLTrackball::mouse_release(
int button,
int ,
int )
104 last_point_ok_ =
false;
105 button_down_[button] =
false;
109 zoom(0, (
int)(last_point_2D_[1] - 0.05*glstate_.viewport_width()));
110 else if (button == 4)
111 zoom(0, (
int)(last_point_2D_[1] + 0.05*glstate_.viewport_width()));
119 GLTrackball::mouse_move(
int x,
int y)
121 if (button_down_[0] && button_down_[1])
123 else if (button_down_[0])
125 else if (button_down_[1])
126 action_ = TRANSLATION;
130 case ROTATION: rotation(x, y);
break;
131 case TRANSLATION: translation(x, y);
break;
132 case ZOOM: zoom(x, y);
break;
136 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
144 GLTrackball::rotation(
int x,
int y)
153 new_point_ok_ = map_to_sphere(new_point_2D_, new_point_3D_);
157 Vec3f axis = (last_point_3D_ % new_point_3D_);
158 float cos_angle = (last_point_3D_ | new_point_3D_);
160 if (fabs(cos_angle) < 1.0)
162 double angle = 2.0*acos(cos_angle) * 180.0 / M_PI;
164 Vec3d t = glstate_.modelview().transform_point(center_);
165 glstate_.translate(-t[0], -t[1], -t[2], MULT_FROM_LEFT);
166 glstate_.rotate(angle, axis[0], axis[1], axis[2], MULT_FROM_LEFT);
167 glstate_.translate( t[0], t[1], t[2], MULT_FROM_LEFT);
178 GLTrackball::translation(
int x,
int y)
180 double dx = double(x - last_point_2D_[0]);
181 double dy = double(y - last_point_2D_[1]);
183 double z = glstate_.modelview().transform_point(center_)[2];
184 double w = double(glstate_.viewport_width());
185 double h = double(glstate_.viewport_height());
186 double fovy = double(glstate_.fovy());
187 double nearpl = double(glstate_.near_plane());
189 double aspect = w / h;
190 double top = double(tan(fovy/2.0*M_PI/180.0) * nearpl);
191 double right = aspect*top;
193 glstate_.translate(-2.0*dx/w*right/nearpl*z,
194 2.0*dy/h*top/nearpl*z,
204 GLTrackball::zoom(
int ,
int y)
206 double dy = double(y - last_point_2D_[1]);
207 double z = glstate_.modelview().transform_point(center_)[2];
208 double h = double(glstate_.viewport_height());
210 glstate_.translate(0.0,
221 GLTrackball::map_to_sphere(
const Vec2i& _point,
Vec3f& _result)
223 float width = float(glstate_.viewport_width());
224 float height = float(glstate_.viewport_height());
226 if ( (_point[0] >= 0) && (_point[0] <= width) &&
227 (_point[1] >= 0) && (_point[1] <= height) )
229 double x = (_point[0] - 0.5*width) / width;
230 double y = (0.5*height - _point[1]) / height;
231 double sinx = sin(M_PI * x * 0.5);
232 double siny = sin(M_PI * y * 0.5);
233 double sinx2siny2 = sinx * sinx + siny * siny;
235 _result[0] = float(sinx);
236 _result[1] = float(siny);
237 _result[2] = sinx2siny2 < 1.0 ? float( sqrt(1.0 - sinx2siny2) ) : 0.0f;
Namespace providing different geometric functions concerning angles.
VectorT< signed int, 2 > Vec2i
VectorT< double, 3 > Vec3d
DLLEXPORT double fovy(int _viewer)
Get field of view angle.
T angle(T _cos_angle, T _sin_angle)