~ubuntu-branches/ubuntu/lucid/glui/lucid

« back to all changes in this revision

Viewing changes to arcball.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2001-09-23 12:57:28 UTC
  • Revision ID: james.westby@ubuntu.com-20010923125728-qbts7xit2eg1ogo2
Tags: upstream-2.1.0.beta
ImportĀ upstreamĀ versionĀ 2.1.0.beta

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 
 
3
  arcball.cpp
 
4
 
 
5
 
 
6
          --------------------------------------------------
 
7
 
 
8
  Copyright (c) 1998 Paul Rademacher
 
9
 
 
10
  This program is freely distributable without licensing fees and is
 
11
  provided without guarantee or warrantee expressed or implied. This
 
12
  program is -not- in the public domain.
 
13
 
 
14
**********************************************************************/
 
15
 
 
16
 
 
17
#include "arcball.h"
 
18
#include <stdio.h>
 
19
 
 
20
 
 
21
/**************************************** Arcball::Arcball() ****/
 
22
/* Default (void) constructor for Arcball                         */
 
23
 
 
24
Arcball::Arcball( void ) 
 
25
{
 
26
  rot_ptr = &rot;
 
27
 
 
28
  init();
 
29
}
 
30
 
 
31
 
 
32
/**************************************** Arcball::Arcball() ****/
 
33
/* Takes as argument a mat4 to use instead of the internal rot  */
 
34
 
 
35
Arcball::Arcball( mat4 *mtx ) 
 
36
{
 
37
  rot_ptr = mtx;
 
38
}
 
39
 
 
40
 
 
41
/**************************************** Arcball::Arcball() ****/
 
42
/* A constructor that accepts the screen center and arcball radius*/
 
43
 
 
44
Arcball::Arcball( vec2 _center, float _radius )
 
45
{
 
46
  rot_ptr = &rot;
 
47
 
 
48
  init();
 
49
  set_params( _center, _radius );
 
50
}
 
51
 
 
52
 
 
53
/************************************** Arcball::set_params() ****/
 
54
 
 
55
void Arcball::set_params( vec2 _center, float _radius )
 
56
{
 
57
  center      = _center;
 
58
  radius      = _radius;
 
59
}
 
60
 
 
61
 
 
62
/*************************************** Arcball::init() **********/
 
63
 
 
64
void Arcball::init( void )
 
65
{
 
66
  center.set( 0.0, 0.0 );
 
67
  radius        = 1.0;
 
68
  q_now         = quat_identity();
 
69
  *rot_ptr      = identity3D();
 
70
  q_increment   = quat_identity();
 
71
  rot_increment = identity3D();
 
72
  is_mouse_down = false;
 
73
  is_spinning   = false;
 
74
  damp_factor   = 0.0;
 
75
  zero_increment = true;
 
76
}
 
77
 
 
78
 
 
79
/*********************************** Arcball::mouse_to_sphere() ****/
 
80
 
 
81
vec3 Arcball::mouse_to_sphere( vec2 p )
 
82
{
 
83
  float mag;
 
84
  vec2  v2 = (p - center) / radius;
 
85
  vec3  v3( v2[0], v2[1], 0.0 );
 
86
  vec3  axis;
 
87
  
 
88
  mag = v2*v2;
 
89
  
 
90
  if ( mag > 1.0 ) {
 
91
    v3.normalize();
 
92
  }
 
93
  else {
 
94
    v3[VZ] = sqrt( 1.0 - mag );
 
95
  }
 
96
 
 
97
  /* Now we add constraints - X takes precedence over Y */
 
98
  if ( constraint_x ) {
 
99
    v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 ));
 
100
  } else if ( constraint_y ) {
 
101
    v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 ));
 
102
  }
 
103
  
 
104
  return v3;
 
105
}
 
106
 
 
107
 
 
108
/************************************ Arcball::constrain_vector() ****/
 
109
 
 
110
vec3 Arcball::constrain_vector( vec3 vector, vec3 axis )
 
111
{
 
112
  return (vector-(vector*axis)*axis).normalize();
 
113
}
 
114
 
 
115
/************************************ Arcball::mouse_down() **********/
 
116
 
 
117
void Arcball::mouse_down( int x, int y )
 
118
{
 
119
  down_pt.set( (float)x, (float) y );
 
120
  is_mouse_down = true;
 
121
 
 
122
  q_increment   = quat_identity();
 
123
  rot_increment = identity3D();
 
124
  zero_increment = true;
 
125
}
 
126
 
 
127
 
 
128
/************************************ Arcball::mouse_up() **********/
 
129
 
 
130
void Arcball::mouse_up( void )
 
131
{
 
132
  q_now = q_drag * q_now;
 
133
  is_mouse_down = false;
 
134
}
 
135
 
 
136
 
 
137
/********************************** Arcball::mouse_motion() **********/
 
138
 
 
139
void Arcball::mouse_motion( int x, int y, int shift, int ctrl, int alt )
 
140
{
 
141
  /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
 
142
  set_constraints( ctrl != 0, alt != 0 );
 
143
 
 
144
  vec2 new_pt( (float)x, (float) y );
 
145
  vec3 v0 = mouse_to_sphere( down_pt );
 
146
  vec3 v1 = mouse_to_sphere( new_pt );
 
147
 
 
148
  vec3 cross = v0^v1;
 
149
  
 
150
  q_drag.set( cross, v0 * v1 );
 
151
  
 
152
  //    *rot_ptr = (q_drag * q_now).to_mat4();
 
153
  mat4 temp = q_drag.to_mat4();
 
154
  *rot_ptr = *rot_ptr * temp;
 
155
    
 
156
  down_pt = new_pt;
 
157
 
 
158
        /* We keep a copy of the current incremental rotation (= q_drag) */
 
159
  q_increment   = q_drag;
 
160
  rot_increment = q_increment.to_mat4();
 
161
 
 
162
  set_constraints( false, false );
 
163
 
 
164
  if ( q_increment.s < .999999 ) {
 
165
    is_spinning = true;
 
166
 
 
167
    zero_increment = false;
 
168
  }
 
169
  else {
 
170
    is_spinning = false;
 
171
    zero_increment = true;
 
172
  }
 
173
}
 
174
 
 
175
 
 
176
/********************************** Arcball::mouse_motion() **********/
 
177
 
 
178
void Arcball::mouse_motion( int x, int y )
 
179
{
 
180
  mouse_motion( x, y, 0, 0, 0 );
 
181
}
 
182
 
 
183
 
 
184
/***************************** Arcball::set_constraints() **********/
 
185
 
 
186
void Arcball::set_constraints( Bool _constraint_x, Bool _constraint_y )
 
187
{
 
188
  constraint_x = _constraint_x;
 
189
  constraint_y = _constraint_y;
 
190
}
 
191
 
 
192
/***************************** Arcball::idle() *********************/
 
193
 
 
194
void  Arcball::idle( void )
 
195
{
 
196
  if ( is_mouse_down ) {
 
197
    is_spinning = false;
 
198
    zero_increment = true;
 
199
  }
 
200
 
 
201
  if ( damp_factor < 1.0 ) {
 
202
    q_increment.scale_angle( 1.0 - damp_factor );
 
203
  }
 
204
 
 
205
  rot_increment = q_increment.to_mat4();
 
206
 
 
207
  if ( q_increment.s >= .999999 ) {
 
208
    is_spinning = false;
 
209
    zero_increment = true;
 
210
  }
 
211
}
 
212
 
 
213
 
 
214
/************************ Arcball::set_damping() *********************/
 
215
 
 
216
void  Arcball::set_damping( float d )
 
217
{
 
218
  damp_factor = d;
 
219
}
 
220
 
 
221
 
 
222
 
 
223
 
 
224