Subversion Repositories gelsvn

Rev

Rev 207 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 207 Rev 294
Line 23... Line 23...
23
	// rotation to the point on the object underneath the mouse.  That
23
	// rotation to the point on the object underneath the mouse.  That
24
	// point would then track the mouse as closely as possible.  This is a
24
	// point would then track the mouse as closely as possible.  This is a
25
	// simple example, though, so that is left as an exercise.
25
	// simple example, though, so that is left as an exercise.
26
	ballsize = 2.0f;
26
	ballsize = 2.0f;
27
	screen_centre = Vec2i(width/2, height/2);
27
	screen_centre = Vec2i(width/2, height/2);
28
	qrot = Quaternion(0.0, 0.0, 0.0, 1.0);
28
	qrot = Quatf(0.0, 0.0, 0.0, 1.0);
29
	qinc = Quaternion(0.0, 0.0, 0.0, 1.0);
29
	qinc = Quatf(0.0, 0.0, 0.0, 1.0);
30
	trans = Vec2f(0.0, 0.0);
30
	trans = Vec2f(0.0, 0.0);
31
    }
31
    }
32
    
32
    
33
    void QuatTrackBall::grab_ball(TrackBallAction act, const Vec2i& v)
33
    void QuatTrackBall::grab_ball(TrackBallAction act, const Vec2i& v)
34
    {
34
    {
-
 
35
    if(v[0] < 0 || v[0] >= static_cast<int>(width)
-
 
36
       || v[1] < 0 || v[1] >= static_cast<int>(height))
-
 
37
      return;      
-
 
38
 
35
	set_position(scalePoint(v));
39
	set_position(scalePoint(v));
36
	current_action = act;
40
	current_action = act;
37
    }
41
    }
38
    
42
    
39
    void QuatTrackBall::roll_ball(const Vec2i& v)
43
    void QuatTrackBall::roll_ball(const Vec2i& v)
40
    {
44
    {
-
 
45
    if(v[0] < 0 || v[0] >= static_cast<int>(width)
-
 
46
       || v[1] < 0 || v[1] >= static_cast<int>(height))
-
 
47
      return;      
-
 
48
 
41
	Vec2f w = scalePoint(v); 
49
	Vec2f w = scalePoint(v); 
42
	
50
	
43
	switch (current_action) 
51
	switch (current_action) 
44
	{
52
	{
45
			case ROTATE_ACTION:
53
			case ROTATE_ACTION:
Line 98... Line 106...
98
    
106
    
99
    void QuatTrackBall::calcRotation(const Vec2f& new_pos) 
107
    void QuatTrackBall::calcRotation(const Vec2f& new_pos) 
100
    {
108
    {
101
	// Check for zero rotation
109
	// Check for zero rotation
102
	if (new_pos == last_pos) 
110
	if (new_pos == last_pos) 
103
	    qinc = Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
111
	    qinc = Quatf(0.0f, 0.0f, 0.0f, 1.0f);
104
	else
112
	else
105
	{
113
	{
106
		// Form two vectors based on input points, find rotation axis
114
		// Form two vectors based on input points, find rotation axis
107
		Vec3f p1 = Vec3f(new_pos[0], new_pos[1], projectToSphere(new_pos));
115
		Vec3f p1 = Vec3f(new_pos[0], new_pos[1], projectToSphere(new_pos));
108
		Vec3f p2 = Vec3f(last_pos[0], last_pos[1], projectToSphere(last_pos));
116
		Vec3f p2 = Vec3f(last_pos[0], last_pos[1], projectToSphere(last_pos));
-
 
117
        qinc.make_rot(normalize(p1), normalize(p2));
109
		
118
/*
110
		Vec3f q = cross(p1, p2);		/* axis of rotation from p1 and p2 */
119
		Vec3f q = cross(p1, p2);		// axis of rotation from p1 and p2 
111
		float L = sqrt(1.0f-dot(q,q) / (dot(p1,p1) * dot(p2,p2)));
120
		float L = sqrt(1.0f-dot(q,q) / (dot(p1,p1) * dot(p2,p2)));
112
		
121
		
113
		q.normalize();				/* q' = axis of rotation */
122
		q.normalize();				// q' = axis of rotation 
114
		q *= sqrt((1 - L)/2);	/* q' = q' * sin(phi) */
123
		q *= sqrt((1 - L)/2);	// q' = q' * sin(phi)
115
		
124
		
116
		qinc.set(q[0],q[1],q[2],sqrt((1 + L)/2));
125
		qinc.set(q[0],q[1],q[2],sqrt((1 + L)/2));
-
 
126
*/
117
	    }
127
	}
118
    }
128
    }
119
    
129
    
120
    // Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
130
    // Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
121
    // if we are away from the center of the sphere.
131
    // if we are away from the center of the sphere.
122
    float QuatTrackBall::projectToSphere(const Vec2f& v) 
132
    float QuatTrackBall::projectToSphere(const Vec2f& v) 
123
    {
133
    {
124
	float d, t, z;
134
#ifndef M_SQRT_2
-
 
135
	  const double M_SQRT_2 = 0.707106781187;
-
 
136
#endif
125
	
137
 
126
	d = v.length();
138
      float d = v.length();
-
 
139
      float t = ballsize*M_SQRT_2;
-
 
140
      float z;
127
	
141
  
128
	// Inside sphere 
142
      // Inside sphere 
129
	if (d < ballsize * 0.70710678118654752440) {   
143
      if(d < ballsize) 
130
	    z = sqrt(ballsize*ballsize - d*d);
144
        z = sqrt(ballsize*ballsize - d*d);
-
 
145
      else if(d < t)
131
	}
146
        z = 0.0;
132
	// On hyperbola 
147
      // On hyperbola 
133
	else {           
148
      else 
134
	    t = ballsize / 1.41421356237309504880;
-
 
135
	    z = t*t / d;
149
        z = t*t/d;
136
	}
-
 
137
	
150
 
138
	return z;
151
      return z;
139
    }
152
    }
140
    
153
    
141
    // Scales integer point to the range [-1, 1]
154
    // Scales integer point to the range [-1, 1]
142
    Vec2f QuatTrackBall::scalePoint(const Vec2i& v) const
155
    Vec2f QuatTrackBall::scalePoint(const Vec2i& v) const
143
    {
156
    {
Line 148... Line 161...
148
	return w; 
161
	return w; 
149
    }
162
    }
150
    
163
    
151
    void QuatTrackBall::get_view_param(Vec3f& eye, Vec3f& _centre, Vec3f& up) const
164
    void QuatTrackBall::get_view_param(Vec3f& eye, Vec3f& _centre, Vec3f& up) const
152
    {
165
    {
153
	up  = qrot.apply(Vec3f(0,1,0));
166
	up  = qrot.apply_unit(Vec3f(0,1,0));
154
	Vec3f right = qrot.apply(Vec3f(1,0,0));
167
	Vec3f right = qrot.apply(Vec3f(1,0,0));
155
	_centre = centre - up * trans[1] - right * trans[0]; 
168
	_centre = centre - up * trans[1] - right * trans[0]; 
156
	eye = qrot.apply(Vec3f(0,0,1)*eye_dist) + _centre;
169
	eye = qrot.apply_unit(Vec3f(0,0,1)*eye_dist) + _centre;
157
    }
170
    }
158
    
171
    
159
    
172
    
160
    // Modify the current gl matrix by the trackball rotation and translation.
173
    // Modify the current gl matrix by the trackball rotation and translation.
161
    void QuatTrackBall::set_gl_modelview() const
174
    void QuatTrackBall::set_gl_modelview() const
Line 171... Line 184...
171
		  up[0],up[1],up[2]);
184
		  up[0],up[1],up[2]);
172
    }
185
    }
173
    
186
    
174
    bool QuatTrackBall::is_spinning() const
187
    bool QuatTrackBall::is_spinning() const
175
    {
188
    {
176
	static const Quaternion null_quat(0,0,0,1);
189
	static const Quatf null_quat(0,0,0,1);
177
	if(!(qinc == null_quat))
190
	if(!(qinc == null_quat))
178
	    return true;
191
	    return true;
179
	return false;
192
	return false;
180
    }
193
    }
181
}
194
}