- what ?s
- 3-D interfaces
- imposing a virtual trackball

- As a lab exercise, implement the virtual trackball interface. Rotate a model in a non-axis-aligned away and send me a screenshot.

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.

New things in my brain

To get to them, I need roads

Metaphorical ones

## Comments