CS 455 Lecture 10 – Virtual Trackball
Agenda
- what ?s
- 3-D interfaces
- imposing a virtual trackball
TODO
- As a lab exercise, implement the virtual trackball interface. Rotate a model in a non-axis-aligned away and send me a screenshot.
Code
Pseudocode for mapping a pixel position onto a virtual unit sphere:
project_pixel_onto_ball(x_pixels, y_pixels) do
v_pixels = vec4(x_pixels, y_pixel, 0, 1)
// The pixel is in [0, width] x [0, height]. We want to overlay a
// virtual unit sphere in this window, whose coordinates are
// in [-1, 1] x [-1, 1]. We first scale the pixel location into
// [0, 2] x [0, 2]. Then we shift it into [-1, 1] x [-1, 1].
v_ball = translate by (-1, -1, 0) * scale by (2 / width, 2 / height, 1) * v_pixels
// v_ball.x and v_ball.x tell us the xy-components on this
// virtual sphere, but we don't yet know the z-component.
// However, we do know 1 = x^2 + y^2 + z^2. Let's solve for
// z^2.
z_squared = 1 - v_ball.x ^ 2 - v_ball.y ^ 2
// If xy isn't on the unit sphere, but perhaps in a corner, we
// end up with z_squared < 0. Let's clamp our projection to
// the sphere.
if z_squared < 0
z_squared = 0
end
v_ball.z = z_squared ^ 0.5
normalize v_ball
return v_ball
end
Now, to implement the trackball:
- On left mouse down, persistĀ the mouse location’s projection. Let’s call it fore.
- On left mouse drag:
- Compute the current mouse location’s projection. Let’s call it aft.
- Compute the angle between fore and aft.
- If fore and aft more or less coincident, we don’t need to do anything. Otherwise, compute their cross product. This will be our axis of rotation. Rotate about this axis by the angle between them by asking the
Matrix4
class for help:Matrix4 rotation = Matrix4::GetRotate(theta * 180.0f / 3.14159265358979323846264f, axis);
Note that this rotation represents just the span between the last mouse event and this one. We want to accumulate this rotation with all the previous rotations. We can do so combining this matrix with the earlier transformations. Suppose
xform
is our accumulated transformation, then:xform = rotation * xform;
The order is important. The older rotations in
xform
get applied first, with the new rotation applied last. UploadĀxform
to the vertex shader. Also note that before any mouse events happen,xform
should be the identity matrix. - Make the aft vector be the fore vector for the next drag event.
You might notice the rotation is flipped. Try inverting the near and far parameters on your orthographic projection. The convention is to look down the negative z-axis.
Haiku
New things in my brain
To get to them, I need roads
Metaphorical ones