Changes between Version 12 and Version 13 of MousePicking

Show
Ignore:
Author:
bhook (IP: 64.207.62.170)
Timestamp:
05/18/06 17:13:57 (13 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MousePicking

    v12 v13  
    160160A typical OpenGL projection matrix takes the form: 
    161161 
     162{{{ 
     163#!latex-math-hook 
     164\begin{eqnarray*} 
     165{\boldsymbol P} = \begin{pmatrix} 
     166a & 0 & 0 & 0 \\ 
     1670 & b & 0 & 0 \\ 
     1680 & 0 & c & d \\ 
     1690 & 0 & e & 0 \end{pmatrix} 
     170\end{eqnarray*} 
     171}}} 
     172 
     173The specific coefficient values depend on the nature of the perspective projection matrix (for more information I recommend you look at the documentation for [http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/perspective.html gluPerspective].  These co-efficients should scale and bias the ''x'', ''y'', and ''z'' components of a point while assigning -''z'' to ''w''. 
     174 
     175To transform from view coordinates to clip coordinates: 
     176 
     177{{{ 
     178#!latex-math-hook 
     179\begin{eqnarray*} 
     180{\boldsymbol P}{\boldsymbol v}&=& 
     181{\boldsymbol c}\\ 
     182&=& 
     183\begin{pmatrix} 
     184a{\boldsymbol v}_x\\b{\boldsymbol v}_y\\c{\boldsymbol v}_z 
     185+ d{\boldsymbol v}_w\\e{\boldsymbol v}_z 
     186\end{pmatrix}\\ 
     187\text{where}\\ 
     188{\boldsymbol P}&=&\text{projection matrix as described earlier}\\ 
     189{\boldsymbol v}&=&\text{point in view coordinates}\\ 
     190{\boldsymbol c}&=&\text{point in clipping coordinates}\\ 
     191\end{eqnarray*} 
     192}}} 
     193 
     194So solving for '''v''' we get: 
     195{{{ 
     196#!latex-math-hook 
     197\begin{equation*} 
     198{\boldsymbol v} =  
     199\begin{pmatrix} 
     200\frac{{\boldsymbol c}_x}{a}\\ 
     201\frac{{\boldsymbol c}_y}{b}\\ 
     202\frac{{\boldsymbol c}_w}{e}\\ 
     203\frac{{\boldsymbol c}_z}{d}-\frac{c{\boldsymbol c}_w}{de} 
     204\end{pmatrix} 
     205\end{equation*} 
     206}}} 
     207 
     208Encoding the viewspace to clipspace transformation in a matrix yields the inverse projection matrix: 
     209 
     210{{{ 
     211#!latex-math-hook 
     212\begin{equation*} 
     213{\boldsymbol P}^{-1} = \begin{pmatrix} 
     214\frac{1}{a} & 0 & 0 & 0 \\ 
     2150   & \frac{1}{b} & 0 & 0 \\ 
     2160 & 0 & 0 & \frac{1}{e} \\ 
     2170 & 0 & \frac{1}{d} & -\frac{c}{de} 
     218\end{pmatrix} 
     219\end{equation*} 
     220}}} 
     221 
     222Computing the view coordinate from a clip coordinate is now: 
     223 
     224{{{ 
     225#!latex-math-hook 
     226\begin{equation*} 
     227{\boldsymbol P}^{-1}{\boldsymbol c}={\boldsymbol v} 
     228\end{equation*} 
     229}}} 
     230 
     231There's no guarantee that ''w'' will be 1, so we'll want to rescale appropriately: 
     232 
     233{{{ 
     234#!latex-math-hook 
     235\begin{equation*} 
     236{\boldsymbol v}' = \frac {{\boldsymbol v}}{{\boldsymbol v}_w} 
     237\end{equation*} 
     238}}} 
     239 
     240== Viewspace to Modelspace == 
     241 
     242Finally we just need to go from view coordinates to world coordinates by multiplying the view coordinates against the inverse of the modelview matrix.  Again we can avoid doing a true inverse if we just 
     243logically break down what the modelview transform accomplishes when working with the camera: it is a translation (centering the universe around the camera) and then a rotation (to reflect the camera's 
     244orientation).  The inverse of this is reversed rotation (accomplished with a transpose) followed by a translation with the negation of the modelview matrix's translation component after it has been rotated by the inverse rotation. 
     245 
     246If given our initial modelview matrix '''M''', consisting of a 3x3 rotation submatrix '''R''' and a 3-element translation vector '''t''': 
     247 
     248{{{ 
     249#!latex-math-hook 
     250\begin{equation*} 
     251{\boldsymbol M} = 
     252\begin{pmatrix} 
     253    {\boldsymbol R}_{11} & {\boldsymbol R}_{12} & {\boldsymbol R}_{13} & {\boldsymbol t}_x\\ 
     254    {\boldsymbol R}_{21} & {\boldsymbol R}_{22} & {\boldsymbol R}_{23} & {\boldsymbol t}_y\\ 
     255    {\boldsymbol R}_{31} & {\boldsymbol R}_{32} & {\boldsymbol R}_{33} & {\boldsymbol t}_z\\ 
     256    0 & 0 & 0 & 1 
     257\end{pmatrix}  
     258\end{equation*} 
     259}}} 
     260 
     261Then we can construct the inverse modelview using the transpose of the rotation submatrix and the camera's translation vector: 
     262 
     263{{{ 
     264#!latex-math-hook 
     265\begin{eqnarray*} 
     266{\boldsymbol R}^T{\boldsymbol t}& = &{\boldsymbol t'}\\ 
     267{\boldsymbol M}^{-1} &=& 
     268\begin{pmatrix} 
     269    {\boldsymbol R}^T_{11} & {\boldsymbol R}^T_{12} & {\boldsymbol R}^T_{13} & -{\boldsymbol t'}_x\\ 
     270    {\boldsymbol R}^T_{21} & {\boldsymbol R}^T_{22} & {\boldsymbol R}^T_{23} & -{\boldsymbol t'}_y\\ 
     271    {\boldsymbol R}^T_{31} & {\boldsymbol R}^T_{32} & {\boldsymbol R}^T_{33} & -{\boldsymbol t'}_z\\ 
     272    0 & 0 & 0 & 1 
     273\end{pmatrix} 
     274\end{eqnarray*} 
     275}}} 
     276 
     277If you're specifying the modelview matrix directly, for example by calling {{{glLoadMatrix}}}, then you already have it lying around and you can build the inverse as described earlier.  If, on the other hand, the modelview matrix is built dynamically using something like {{{gluLookAt}}} or a sequence of {{{glTranslate}}}, {{{glRotate}}}, and {{{glScale}}} calls, you can use {{{glGetFloatv}}} to retrieve the current modelview matrix. 
     278 
     279Now that we have the inverse modelview matrix we can use it to transform our view coordinate into world space: 
     280 
     281{{{ 
     282#!latex-math-hook 
     283\begin{eqnarray*} 
     284{\boldsymbol M}^{-1}{\boldsymbol v}&=&{\boldsymbol w}\\ 
     285\text{where}\\ 
     286{\boldsymbol M}^{-1}&=&\text{inverse of the modelview matrix}\\ 
     287{\boldsymbol v}&=&\text{point in viewspace}\\ 
     288{\boldsymbol w}&=&\text{point in worldspace} 
     289\end{eqnarray*} 
     290}}} 
     291 
     292If the depth value under the mouse was used to construct the original viewport coordinate, then '''w''' should correspond to the point in 3-space where the user clicked.  If the depth value was not read then we have an arbitrary point in space with which we can construct a ray from the viewer's position: 
     293 
     294{{{ 
     295#!latex-math-hook 
     296\begin{eqnarray*} 
     297\label{eqn:ray} 
     298\overrightarrow{{\boldsymbol r}}&=&{\boldsymbol a} + t({\boldsymbol w}-{\boldsymbol a})\\ 
     299\text{where}\\ 
     300\overrightarrow{{\boldsymbol r}}&=&\text{ray}\\ 
     301{\boldsymbol a}&=&\text{viewer's position in worldspace}\\ 
     302{\boldsymbol w}&=&\text{point in worldspace}\\ 
     303\end{eqnarray*} 
     304}}}