53 #include "GLTrackball.hh" 66 GLTrackball(GLState& _state)
69 last_point_ok_(false),
72 for (
int i=0; i<10; ++i)
73 button_down_[i] =
false;
81 GLTrackball::mouse_press(
int button,
int x,
int y)
84 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
86 button_down_[button] =
true;
94 GLTrackball::mouse_release(
int button,
int ,
int )
96 last_point_ok_ =
false;
97 button_down_[button] =
false;
101 zoom(0, (
int)(last_point_2D_[1] - 0.05*glstate_.viewport_width()));
102 else if (button == 4)
103 zoom(0, (
int)(last_point_2D_[1] + 0.05*glstate_.viewport_width()));
111 GLTrackball::mouse_move(
int x,
int y)
113 if (button_down_[0] && button_down_[1])
115 else if (button_down_[0])
117 else if (button_down_[1])
118 action_ = TRANSLATION;
122 case ROTATION: rotation(x, y);
break;
123 case TRANSLATION: translation(x, y);
break;
124 case ZOOM: zoom(x, y);
break;
128 last_point_ok_ = map_to_sphere(last_point_2D_, last_point_3D_);
136 GLTrackball::rotation(
int x,
int y)
145 new_point_ok_ = map_to_sphere(new_point_2D_, new_point_3D_);
149 Vec3f axis = (last_point_3D_ % new_point_3D_);
150 float cos_angle = (last_point_3D_ | new_point_3D_);
152 if (fabs(cos_angle) < 1.0)
154 double angle = 2.0*acos(cos_angle) * 180.0 / M_PI;
156 Vec3d t = glstate_.modelview().transform_point(center_);
157 glstate_.translate(-t[0], -t[1], -t[2], MULT_FROM_LEFT);
158 glstate_.rotate(angle, axis[0], axis[1], axis[2], MULT_FROM_LEFT);
159 glstate_.translate( t[0], t[1], t[2], MULT_FROM_LEFT);
170 GLTrackball::translation(
int x,
int y)
172 double dx = double(x - last_point_2D_[0]);
173 double dy = double(y - last_point_2D_[1]);
175 double z = glstate_.modelview().transform_point(center_)[2];
176 double w = double(glstate_.viewport_width());
177 double h = double(glstate_.viewport_height());
178 double fovy = double(glstate_.fovy());
179 double nearpl = double(glstate_.near_plane());
182 double top = double(tan(fovy/2.0*M_PI/180.0) * nearpl);
183 double right = aspect*top;
185 glstate_.translate(-2.0*dx/w*right/nearpl*z,
186 2.0*dy/h*top/nearpl*z,
196 GLTrackball::zoom(
int ,
int y)
198 double dy = double(y - last_point_2D_[1]);
199 double z = glstate_.modelview().transform_point(center_)[2];
200 double h = double(glstate_.viewport_height());
202 glstate_.translate(0.0,
213 GLTrackball::map_to_sphere(
const Vec2i& _point,
Vec3f& _result)
215 float width = float(glstate_.viewport_width());
216 float height = float(glstate_.viewport_height());
218 if ( (_point[0] >= 0) && (_point[0] <= width) &&
219 (_point[1] >= 0) && (_point[1] <= height) )
221 double x = (_point[0] - 0.5*width) / width;
222 double y = (0.5*height - _point[1]) / height;
223 double sinx = sin(M_PI * x * 0.5);
224 double siny = sin(M_PI * y * 0.5);
225 double sinx2siny2 = sinx * sinx + siny * siny;
227 _result[0] = float(sinx);
228 _result[1] = float(siny);
229 _result[2] = sinx2siny2 < 1.0 ? float( sqrt(1.0 - sinx2siny2) ) : 0.0f;
double fovy() const
get field of view in y direction
VectorT< signed int, 2 > Vec2i
double aspect() const
get aspect ratio
Namespace providing different geometric functions concerning angles.
T angle(T _cos_angle, T _sin_angle)
Vec3d right() const
get right-vector w.r.t. camera coordinates
VectorT< double, 3 > Vec3d