1 /**********************************************************************
6 --------------------------------------------------
8 GLUI User Interface Toolkit (LGPL)
9 Copyright (c) 1998 Paul Rademacher
10 Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
11 Oct 2003, Nigel Stewart - GLUI Code Cleaning
13 WWW: http://sourceforge.net/projects/glui/
14 Forums: http://sourceforge.net/forum/?group_id=92496
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Lesser General Public
18 License as published by the Free Software Foundation; either
19 version 2.1 of the License, or (at your option) any later version.
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 Lesser General Public License for more details.
26 You should have received a copy of the GNU Lesser General Public
27 License along with this library; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 **********************************************************************/
37 /**************************************** Arcball::Arcball() ****/
38 /* Default (void) constructor for Arcball */
46 /**************************************** Arcball::Arcball() ****/
47 /* Takes as argument a mat4 to use instead of the internal rot */
49 Arcball::Arcball(mat4 *mtx)
55 /**************************************** Arcball::Arcball() ****/
56 /* A constructor that accepts the screen center and arcball radius*/
58 Arcball::Arcball(const vec2 &_center, float _radius)
62 set_params(_center, _radius);
66 /************************************** Arcball::set_params() ****/
68 void Arcball::set_params(const vec2 &_center, float _radius)
74 /*************************************** Arcball::init() **********/
78 center.set( 0.0, 0.0 );
80 q_now = quat_identity();
81 *rot_ptr = identity3D();
82 q_increment = quat_identity();
83 rot_increment = identity3D();
84 is_mouse_down = false;
87 zero_increment = true;
90 /*********************************** Arcball::mouse_to_sphere() ****/
92 vec3 Arcball::mouse_to_sphere(const vec2 &p)
95 vec2 v2 = (p - center) / radius;
96 vec3 v3( v2[0], v2[1], 0.0 );
103 v3[VZ] = (float) sqrt( 1.0 - mag );
105 /* Now we add constraints - X takes precedence over Y */
108 v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 ));
110 else if ( constraint_y )
112 v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 ));
119 /************************************ Arcball::constrain_vector() ****/
121 vec3 Arcball::constrain_vector(const vec3 &vector, const vec3 &axis)
123 return (vector-(vector*axis)*axis).normalize();
126 /************************************ Arcball::mouse_down() **********/
128 void Arcball::mouse_down(int x, int y)
130 down_pt.set( (float)x, (float) y );
131 is_mouse_down = true;
133 q_increment = quat_identity();
134 rot_increment = identity3D();
135 zero_increment = true;
139 /************************************ Arcball::mouse_up() **********/
141 void Arcball::mouse_up()
143 q_now = q_drag * q_now;
144 is_mouse_down = false;
148 /********************************** Arcball::mouse_motion() **********/
150 void Arcball::mouse_motion(int x, int y, int shift, int ctrl, int alt)
152 /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
153 set_constraints( ctrl != 0, alt != 0 );
155 vec2 new_pt( (float)x, (float) y );
156 vec3 v0 = mouse_to_sphere( down_pt );
157 vec3 v1 = mouse_to_sphere( new_pt );
161 q_drag.set( cross, v0 * v1 );
163 // *rot_ptr = (q_drag * q_now).to_mat4();
164 mat4 temp = q_drag.to_mat4();
165 *rot_ptr = *rot_ptr * temp;
169 /* We keep a copy of the current incremental rotation (= q_drag) */
170 q_increment = q_drag;
171 rot_increment = q_increment.to_mat4();
173 set_constraints(false, false);
175 if ( q_increment.s < .999999 )
178 zero_increment = false;
183 zero_increment = true;
188 /********************************** Arcball::mouse_motion() **********/
190 void Arcball::mouse_motion(int x, int y)
192 mouse_motion(x, y, 0, 0, 0);
196 /***************************** Arcball::set_constraints() **********/
198 void Arcball::set_constraints(bool _constraint_x, bool _constraint_y)
200 constraint_x = _constraint_x;
201 constraint_y = _constraint_y;
204 /***************************** Arcball::idle() *********************/
211 zero_increment = true;
214 if (damp_factor < 1.0f)
215 q_increment.scale_angle(1.0f - damp_factor);
217 rot_increment = q_increment.to_mat4();
219 if (q_increment.s >= .999999f)
222 zero_increment = true;
227 /************************ Arcball::set_damping() *********************/
229 void Arcball::set_damping(float d)