
\documentclass[11pt]{article}
\usepackage{fleqn}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{epsfig}
\usepackage{makeidx}
% if you want to include PostScript figures
\usepackage{graphicx}

\parindent =0pt
\parskip = 6pt
\tolerance = 10000

\newcommand{\aaa}{\ensuremath{\mathbf{a}}}
\newcommand{\ee}{\ensuremath{\mathbf{e}}}
\newcommand{\Lll}{\ensuremath{\mathbf{l}}}
\newcommand{\vv}{\ensuremath{\mathbf{v}}}
\newcommand{\uu}{\ensuremath{\mathbf{u}}}
\newcommand{\ww}{\ensuremath{\mathbf{w}}}
\newcommand{\xx}{\ensuremath{\mathbf{x}}}
\newcommand{\rr}{\ensuremath{\mathbf{r}}}
\newcommand{\pp}{\ensuremath{\mathbf{p}}}
\newcommand{\oo}{\ensuremath{\mathbf{o}}}
\newcommand{\sss}{\ensuremath{\mathbf{s}}}
\newcommand{\mm}{\ensuremath{\mathbf{m}}}
% ===========================================================

\title{Viewing\\ Introduction to Computer Graphics \\ Arizona State University}

\author{Dianne Hansford}
\date{\today}


\begin{document}


\maketitle


\section{Introduction}\label{sec:intro}

The Viewing Pipeline involves several coordinate systems, namely
$$
\textrm{object}\rightarrow\textrm{world}\rightarrow\textrm{eye}
\rightarrow\textrm{clip}\rightarrow
\textrm{NDC}\rightarrow\textrm{window}.
$$
These coordinate transformations have been designed to optimize the
algorithms applied to a primitive traveling down the pipeline. The
discussion here focuses on the transformation from world to eye
coordinates. This transformation is commonly described in terms of
setting-up a camera.


\section{Setting-up the Camera}
\label{sec:setup}

Let's assume that we have placed the geometry that we would like to
display in a world coordinate system. Soon we will want to define
the type of projection (orthographic or perspective) and the
specifics of the projection. Standard practice is to make the
$xy$--plane the projection plane. Thus to facilitate defining the
projection step, we move our geometry to sit  ``centered" on the
$-z$--axis, and this is called eye coordinates. Just how we move and
orient our geometry into eye coordinates is conveniently defined by
the parameters analogous to setting up a camera in the world
coordinate system.

Specifically, setting-up a camera involves choosing
\begin{itemize}
\item its location, $\ee$ (called the {\em eye point}),
\item its line of sight, defined by the line through the eye and a point $\aaa$
(called the {\em at point}), and
\item its orientation, $\uu$ (called the {\em up vector}).
\end{itemize}
These parameters are illustrated in Figure \ref{fig:camera-setup}.
There are a few restrictions on these camera parameters. The eye and
at point must not be identical. The up vector determines how our
camera is rotated. For instance, will the final image appear
horizontally or vertically? The up vector does not need to be
orthogonal to the line of sight, $\aaa - \ee$. Obviously the up
vector must not be the zero vector. See Section \ref{sec:how} for a
closer examination of the up vector.



Now we have the means for describing the orientation of our geometry
on the $-z$--axis. The viewing operation will take
\begin{itemize}
\item the eye point to the origin,
\item the at point onto the $-z$--axis, and
\item the up vector will lie in the $+yz$-plane.
\end{itemize}
This is illusrated in Figure \ref{fig:camera-eye}


\begin{figure}
    \begin{center}
    \epsfig{file=figures/viewing-camera-setup.eps, height = 3 in}
    \end{center}
    \caption{Setting-up the camera in world coordinates.}
  \label{fig:camera-setup}
\end{figure}


\begin{figure}
    \begin{center}
    \epsfig{file=figures/viewing-camera-eye.eps, height = 3 in}
    \end{center}
    \caption{The camera's position in eye coordinates.}
  \label{fig:camera-eye}
\end{figure}

In OpenGL, defining the camera and moving the geometry to eye
coordinates is as simple as calling
$$
    \textrm{gluLookAt}(\ee, \aaa, \uu).
$$


\section{How Does gluLookAt Work?}
\label{sec:how}

Suppose a vertex of our geometry in world coordinates is labeled
$\pp_w$, and the corresponding point in eye coordinates is labeled
$\pp_e$. Using our knowledge of the connection between linear maps
and coordinate transformations, the gluLookAt transformation is very
easy to construct!

To review: recall that a matrix $A = \begin{bmatrix} \aaa_1 & \aaa_2
& \aaa_3\end{bmatrix}$ defines a linear map that maps a vector $\vv$
in the $[\ee_1, \ee_2, \ee_3]$--coordinate system to a vector $\vv'$
in the $[\aaa_1, \aaa_2, \aaa_3]$--coordinate system,
$$
   \vv' = A\vv.
$$
Our problem here is simply a coordinate transformation, so the goal
is to stage it in this context.

The first step is to form an orthonormal frame (a set of orthogonal
unit vectors) from the camera parameters,
$$
  \Lll = \frac{\aaa - \ee}{\|\aaa - \ee\|}, \qquad
  \rr = \frac{\Lll \wedge \uu}{\|\Lll \wedge\uu\|}, \qquad
  \sss = \rr \wedge \Lll,
$$
where $\Lll$ is called the {\em line of sight vector}. Notice that
$\rr$ is on our right as we look down the line of sight. And then
$\sss$ will correspond to the up-direction. Now we see that all
$\uu$ vectors that form the same plane with $\Lll$ fall into two
groups, and each group forms the ``upside-down" image of the other.
Thus the angle between $\uu$ and $\Lll$ is inconsequential, however
the side of $\Lll$ in this plane is a determining factor in the
resulting orientation.

In Section \ref{sec:setup}, the camera's transformation from world
to eye coordinates was outlined. In terms of this orthonormal frame,
we want
$$
  \Lll \rightarrow -\ee_3 \qquad
  \rr \rightarrow \ee_1 \qquad
  \sss \rightarrow \ee_2.
$$
However, before we align our orthonormal frame with the coordinate
axes, we need to translate the geometry by $-\ee$, that is $\pp_w -
\ee. $

Bringing in the geometric interpretation of a linear map, we can
construct a matrix such that
\begin{align*}
  \begin{bmatrix} \rr & \sss & -\Lll\end{bmatrix}\pp_e &= (\pp_w -
  \ee)\\
  A\pp_e &= (\pp_w - \ee).
\end{align*}
However, $\pp_e$ is unknown, so we need the matrix $A^{-1}$ which
forms
$$
  \pp_e = A^{-1}(\pp_w - \ee).
$$
Now we can take advantage of having formed an orthonormal frame:
$A^{-1} = A^{{\rm T}}$.  Hence
\begin{equation}
  \pp_e = A^{{\rm T}}(\pp_w - \ee)  =
   \begin{bmatrix} \rr^{{\rm T}} \\ \sss^{{\rm T}} \\ -\Lll^{{\rm
  T}}\end{bmatrix}(\pp_w - \ee),
  \label{eq:w-to-e}
\end{equation}
and we have our transformation to eye coordinates.



\section{A Numerical Example}

This is a simple example to keep the calculations easy to follow.
Suppose our modeling transformations place our object on the
$-x$--axis as illustrated in Figure \ref{fig:ex-world}. Let's set up
our camera with the following parameters
$$
  \ee = \begin{bmatrix}  0 \\ 0 \\ 0\end{bmatrix}\qquad
  \aaa = \begin{bmatrix} -1 \\ 0 \\ 0\end{bmatrix}\qquad
  \uu = \begin{bmatrix} 0 \\ 0 \\ 1 \end{bmatrix}.
$$

From this camera set-up, we form the following orthonormal frame
$$
  \Lll = \begin{bmatrix}  -1 \\ 0 \\ 0\end{bmatrix}\qquad
  \rr = \begin{bmatrix}  0 \\ 1 \\ 0\end{bmatrix}\qquad
  \sss = \begin{bmatrix}  0 \\ 0 \\ 1\end{bmatrix},
$$
which is also illustrated in Figure  \ref{fig:ex-world}.


\begin{figure}
    \begin{center}
    \epsfig{file=figures/viewing-ex-world, height = 3 in}
    \end{center}
    \caption{An example object and camera in world coordinates.}
  \label{fig:ex-world}
\end{figure}



Since the camera is already located at the origin, a translation is
not necessary, and
$$
  A = \begin{bmatrix} 0 & 0 & 1\\
                          1 & 0 & 0\\
                          0 & 1 & 0\end{bmatrix}.
$$
Thus the eye coordinate points $\pp_e$ are calculated as
$$
  \pp_e = \begin{bmatrix} 0 & 1 & 0\\
                          0 & 0 & 1\\
                          1 & 0 & 0\end{bmatrix}\pp_w.
$$


 Let's check that our
original  goals, that the at point is mapped to the $-z$--axis and
the up vector is mapped to the $+yz$--plane are satisfied:
$$
  A^{{\rm T}}\aaa = \begin{bmatrix}0 \\ 0 \\ -1\end{bmatrix}\quad
  \textrm{and}\quad
  A^{{\rm T}}\uu = \begin{bmatrix} 0 \\ 1 \\ 0\end{bmatrix},
$$
which indeed does satisfy the requirements.

\begin{figure}
    \begin{center}
    \epsfig{file=figures/viewing-ex-eye.eps, height = 3 in}
    \end{center}
    \caption{An example object and camera in eye coordinates.}
  \label{fig:ex-eye}
\end{figure}


The final view of the object is illustrated in Figure
\ref{fig:ex-finalview}.


\begin{figure}
    \begin{center}
    \epsfig{file=figures/viewing-ex-final, height = 3 in}
    \end{center}
    \caption{The final view resulting from the example camera parameters.}
  \label{fig:ex-finalview}
\end{figure}


\section{OpenGL and the ModelView Matrix}

In OpenGL, the transformation of vertices from world to eye
coordinates is done via the ModelView matrix. The modeling
operations, such as glRotate or glTranslate, are the tools for
positioning our geometry in the world system. The viewing
transformation tool, gluLookAt, simply utilizes the rotate and
translate operations, so in that sense,  modeling and viewing are
interchangeable. In fact, consider achieving the displayed effect of
 an object rotating about its centroid --- this could be achieved by
either rotating the object or rotating the eye about the object.
Thus modeling and viewing have been concatenated  to form
"ModelView".


The gluLookAt affine map (\ref{eq:w-to-e}) is stored in the $4\times
4$ ModelView matrix. To do this,  first we express our points in
homogenous form,
$$
  \bar{\pp}_w = \begin{bmatrix} p_x\\ p_y \\ p_z \\ 1\end{bmatrix}.
$$
The translation followed by the rotation in (\ref{eq:w-to-e}) is
written as
$$
    \bar{\pp}_e  =
\begin{tabular}{|c|c|}
        \hline
        $
        A^{{\rm T}}$  &
                        $\oo$  \\
        \hline
        $\begin{matrix}
         ~\quad 0 & ~~\quad 0&~\quad  0
        \end{matrix}$ &
        $1$  \\
        \hline
\end{tabular}
\quad
\begin{tabular}{|c|c|}
        \hline
        $
        I$  &
                        $-\ee$  \\
        \hline
        $\begin{matrix}
         ~\quad 0 & ~~\quad 0&~\quad  0
        \end{matrix}$ &
        $1$  \\
        \hline
\end{tabular}
    \quad\bar{\pp}_w.
$$
Multiplying the translation and rotation matrices, we have
 $$ \bar{\pp}_e =
\begin{tabular}{|c|c|}
        \hline
        $
        A^{{\rm T}}$  &
                        $A^{{\rm T}}(-\ee)$  \\
        \hline
        $\begin{matrix}
         ~\quad 0 & ~~\quad 0&~\quad  0
        \end{matrix}$ &
        $1$  \\
        \hline
\end{tabular}
\quad\bar{\pp}_w
$$




Keep in mind that we specify the transformation commands in our
program in the reverse order than we want them applied. Let $R$ be
the matrix formed from a modeling command such as glRotate, and $L$
be the matrix formed from gluLookAt.  Normally we apply our modeling
transformations and then set up the camera, so for a vertex $\vv$ we
want $LR\vv$. In OpenGL this would require our code to take the form

$\vdots$\\
gluLookAt \\
glRotate \\
draw $\vv$ \\
$\vdots$




\section{Getting Started: Creating the Eye, At, and Up Parameters}
\label{sec:creating}

Often times we input a geometric object from a file, and without
knowledge of its exact shape or orientation, we need to determine
suitable parameters for gluLookAt. One suggestion is as follows.

Upon reading the vertices, record the minimum and maximum values in
$x$, $y$, and $z$. This is called the {\em minmax box}. Thus, the
minmax box contains the object and it is aligned with the coordinate
axes. Let the lower-left-most corner and upper-right-most corner be
$$
\mm_0 = \begin{bmatrix} m_{0,0} \\ m_{1,0} \\
m_{2,0}\end{bmatrix}\quad\textrm{and}\quad
\mm_1 = \begin{bmatrix} m_{0,1} \\
m_{1,1} \\ m_{2,1}\end{bmatrix},
$$
respectively.

A good choice for the at point $\aaa$ is the centroid of the minmax
box,
$$
  \aaa = \frac{1}{2}(\mm_0 + \mm_1).
$$
A good choice for the up vector is one of the coordinate axes, for
instance the $z$--axis,
$$
  \uu = \begin{bmatrix} 0 \\ 0 \\ 1\end{bmatrix}.
$$
And finally, the eye point could be chosen some distance away from a
face of the minmax box, but not so that the up vector is parallel to
the line of sight. For instance, we could view the object from in
front of an $xy$-face of the minmax box:
$$
  \ee = \aaa - 2.0\times(\begin{bmatrix} m_{0,0} \\ m_{1,1} \\
  m_{2,0}\end{bmatrix} - \begin{bmatrix} m_{0,0} \\ m_{1,0} \\
  m_{2,0}\end{bmatrix}),
$$
which steps back from $\aaa$, twice the $y$-dimension of the minmax
box.


\section{Camera Handling}

In Section \ref{sec:creating}, a very simple solution for specifying
the camera's set-up was presented. For animated graphics, such as
games, the camera set-up is much more involved, and this is commonly
known as {\em camera handling}.

Considering the gaming application, some of the concerns include the
following.
\begin{itemize}
\item Should the gamer's avatar always be in view?
\item Are important elements of the game, such as enemies or cliffs,
in full view?
\item Is the camera in a physically impossible location, such as
behind a wall?
\item Should the gamer have control of the camera?
\end{itemize}

Key: There is no one, correct solution. Gaming companies are
constantly experimenting with different camera handling schemes to
achieve a novel look for their game. For instance, ``FPS" (First
Person Shooter) was novel when it came out because it was the first
use of the camera at the eyes of the avatar, that is, first person
I. You cannot actually see your avatar; perhaps only your arms or
firearm. This approach gained widespread acceptance, as it was used
in games such as Doom, Quake, and Unreal Tournament. This immersive
viewpoint allows gamers to identify closely with an avatar.

Another popular camera handling approach is ``third person", where
the camera would be just behind your head. Now you can see a bit
more of your avatar, and peripheral vision is simulated. Tomb Raider
implements this approach.



\end{document}
