source: trunk/src/testing/app/volvis/Trackball.cpp @ 4

Revision 4, 5.8 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1//
2// ============================================================
3//                     === OpenGL Library ===
4//
5// $Date: 2004/10/28 22:43:53 $
6// $Revision: 1.1 $
7//
8// Hacked into C++ from SGI's trackball.h---see copyright
9// at end.
10//
11// ============================================================
12//
13
14#include <iostream.h>
15#include <string.h>
16#include <limits.h>
17#include <assert.h>
18#include <math.h>
19
20#include "Trackball.h"
21#include "VectorMath.h"
22#include "MatrixMath.h"
23
24
25//===========================================================================
26//===========================================================================
27// Static Initialization
28//===========================================================================
29//===========================================================================
30
31//  This size should really be based on the distance from the center of
32//  rotation to the point on the object underneath the mouse.  That
33//  point would then track the mouse as closely as possible.  This is a
34//  simple example, though, so that is left as an Exercise for the
35//  Programmer.
36float  Trackball::trackballSize = (float)0.9;
37
38//  Number of iterations before we renormalize.
39int  Trackball::renormCount = 97;
40
41
42//===========================================================================
43//===========================================================================
44// Constructors/Destructor
45//===========================================================================
46//===========================================================================
47
48Trackball::Trackball()
49{
50  lastX = 0.0;
51  lastY = 0.0;
52  vZero(lastQuat);
53  vZero(curQuat);
54  lastQuat[3] = 1.0;
55  curQuat[3] = 1.0;
56}
57
58
59Trackball::~Trackball()
60{
61  //  Empty.
62}
63
64
65
66//===========================================================================
67// Public Member Functions
68//===========================================================================
69
70void
71Trackball::start(float x, float y)
72{
73  lastX = x;
74  lastY = y;
75  vZero(lastQuat);
76  lastQuat[3] = 1.0;
77}
78
79
80
81/////////////////////////////////////////////////////////////////////////////
82//
83//  Ok, simulate a track-ball.  Project the points onto the virtual
84//  trackball, then figure out the axis of rotation, which is the cross
85//  product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
86//  Note:  This is a deformed trackball-- is a trackball in the center,
87//  but is deformed into a hyperbolic sheet of rotation away from the
88//  center.  This particular function was chosen after trying out
89//  several variations.
90//
91//  It is assumed that the arguments to this routine are in the range
92//  (-1.0 ... 1.0)
93//
94void
95Trackball::update(float x, float y)
96{
97  float p1[3], p2[3], d[3];
98  float t;
99
100  //  Might just be able to return here.
101  if (lastX == x && lastY == y) {
102    /* Zero rotation */
103    vZero(lastQuat);
104    lastQuat[3] = 1.0;
105    return;
106  }
107
108  /*
109   * First, figure out z-coordinates for projection of P1 and P2 to
110   * deformed sphere
111   */
112  vSet(p1, lastX, lastY, projectToSphere(trackballSize, lastX, lastY));
113  vSet(p2, x,     y,     projectToSphere(trackballSize,  x,    y));
114
115  /*
116   *  Now, we want the cross product of P1 and P2
117   */
118  vCross(p2, p1, a);
119
120  /*
121   *  Figure out how much to rotate around that axis.
122   */
123  vSub(p1,p2,d);
124  t = (float)(vLength(d) / (2.0*trackballSize));
125
126  /*
127   * Avoid problems with out-of-control values...
128   */
129  if (t > 1.0) t = 1.0;
130  if (t < -1.0) t = -1.0;
131  phi = (float)(2.0 * asin(t));
132
133  axisToQuat(a, phi, lastQuat);
134
135  lastX = x;
136  lastY = y;
137
138  addQuats(lastQuat, curQuat, curQuat);
139}
140
141//get the axis and angle for the rotation
142void Trackball::getAxisAngle(float& angle, float axis[3]) {
143        angle = phi*180.0f/3.141517;
144        for (int i=0;i<3;i++)
145                axis[i] = a[i];
146}
147
148/////////////////////////////////////////////////////////////////////////////
149// joeys clear
150//
151void
152Trackball::clear()
153{
154  lastX = 0.0;
155  lastY = 0.0;
156  vZero(lastQuat);
157  vZero(curQuat);
158  lastQuat[3] = 1.0;
159  curQuat[3] = 1.0;
160}
161
162
163
164/////////////////////////////////////////////////////////////////////////////
165//
166//  Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
167//  if we are away from the center of the sphere.
168//
169float
170Trackball::projectToSphere(float r, float x, float y)
171{
172  float d, t, z;
173
174  d = (float)(sqrt(x*x + y*y));
175  if (d < r * 0.70710678118654752440) {    /* Inside sphere */
176    z = (float)(sqrt(r*r - d*d));
177  } else {           /* On hyperbola */
178    t = (float)(r / 1.41421356237309504880);
179    z = t*t / d;
180  }
181  return z;
182}
183
184
185
186/////////////////////////////////////////////////////////////////////////////
187//
188//  Build a rotation matrix, given a quaternion rotation.
189//
190void
191Trackball::buildRotMatrix(float m[4][4])
192{
193  m[0][0] = (float)(1.0 - 2.0 * (curQuat[1] * curQuat[1] + curQuat[2] * curQuat[2]));
194  m[0][1] = (float)(2.0 * (curQuat[0] * curQuat[1] - curQuat[2] * curQuat[3]));
195  m[0][2] = (float)(2.0 * (curQuat[2] * curQuat[0] + curQuat[1] * curQuat[3]));
196  m[0][3] = (float)(0.0);
197
198  m[1][0] = (float)(2.0 * (curQuat[0] * curQuat[1] + curQuat[2] * curQuat[3]));
199  m[1][1]= (float)(1.0 - 2.0 * (curQuat[2] * curQuat[2] + curQuat[0] * curQuat[0]));
200  m[1][2] = (float)(2.0 * (curQuat[1] * curQuat[2] - curQuat[0] * curQuat[3]));
201  m[1][3] = (float)(0.0);
202
203  m[2][0] = (float)(2.0 * (curQuat[2] * curQuat[0] - curQuat[1] * curQuat[3]));
204  m[2][1] = (float)(2.0 * (curQuat[1] * curQuat[2] + curQuat[0] * curQuat[3]));
205  m[2][2] = (float)(1.0 - 2.0 * (curQuat[1] * curQuat[1] + curQuat[0] * curQuat[0]));
206  m[2][3] = (float)(0.0);
207
208  m[3][0] = (float)(0.0);
209  m[3][1] = (float)(0.0);
210  m[3][2] = (float)(0.0);
211  m[3][3] = (float)(1.0);
212}
213
214void
215Trackball::reapply()
216{
217  addQuats(lastQuat, curQuat, curQuat);
218}
Note: See TracBrowser for help on using the repository browser.