1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<HTML>
3<HEAD>
4<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
5<META name="GENERATOR" content="Microsoft FrontPage 5.0">
6<META http-equiv="Content-Style-Type" content="text/css">
7<LINK rel="stylesheet" type="text/css" href="../../CSS/revolution.css">
8<TITLE>Mtx, MtxPtr</TITLE>
9</HEAD>
10<BODY>
11<H1 align="left">Mtx, MtxPtr</H1>
12<H2 align="left">C Specification</H2>
13<BLOCKQUOTE><CODE><code>#include &lt;revolution/mtx/GeoTypes.h&gt;<BR> <BR> typedef f32 Mtx[3][4];<BR> typedef f32 (*MtxPtr)[4];<BR> <BR> #define MTX_PTR_OFFSET &nbsp;&nbsp; 3</CODE></CODE>
14</BLOCKQUOTE>
15<H2 align="left">Description</H2>
16<P><strong>Mtx<em> </em></strong>is a 3-row, 4-column two-dimensional array of 12 floating-point values.&nbsp;It's used by the matrix library as a 3x4 transformation matrix.&nbsp;In this context, it has an implied fourth row of (<CODE>0,0,0,1</CODE>).&nbsp;3x4 matrices are used by all <EM><STRONG><code>MTX</code></STRONG></EM>-prefixed functions except those involving projection.&nbsp;These functions (<a href="../Projection/MTXFrustum.html"><code>MTXFrustum</code></a>, <a href="../Projection/MTXPerspective.html"><code>MTXPerspective</code></a> and <a href="../Projection/MTXOrtho.html"><code>MTXOrtho</code></a>) all require a true 4x4 matrix (see <a href="../structures/Mtx44_Mtx44Ptr.html"><code>Mtx44, Mtx44Ptr</code></a>).</P>
17<P>Matrices are stored and dereferenced C-style in row-major format.&nbsp;The table below summarizes the three ways of looking at a matrix:&nbsp;in memory, from a mathematical viewpoint, and as a C-style array.</P>
18<DIV align="center">
19<CENTER>
20<TABLE border="1" cellspacing="1" cellpadding="7" width="400">
21  <TBODY>
22    <TR>
23<TD width="29%" valign="TOP" bgcolor="#ffffff">address</TD>
24<TD width="31%" valign="TOP" bgcolor="#ffffff">Mathematical</TD>
25<TD width="40%" valign="TOP" bgcolor="#ffffff">C arrays</TD>
26    </TR>
27    <TR>
28<TD width="29%" valign="TOP"><FONT size="2">0x80200080</FONT></TD>
29<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>00</SUB></I></FONT></TD>
30<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[0][0]</FONT></TD>
31    </TR>
32    <TR>
33<TD width="29%" valign="TOP"><FONT size="2">0x80200084</FONT></TD>
34<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>01</SUB></I></FONT></TD>
35<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[0][1]</FONT></TD>
36    </TR>
37    <TR>
38<TD width="29%" valign="TOP"><FONT size="2">0x80200088</FONT></TD>
39<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>02</SUB></I></FONT></TD>
40<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[0][2]</FONT></TD>
41    </TR>
42    <TR>
43<TD width="29%" valign="TOP"><FONT size="2">0x8020008c</FONT></TD>
44<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>03</SUB></I></FONT></TD>
45<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[0][3]</FONT></TD>
46    </TR>
47    <TR>
48<TD width="29%" valign="TOP"><FONT size="2">0x80200090</FONT></TD>
49<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>10</SUB></I></FONT></TD>
50<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[1][0]</FONT></TD>
51    </TR>
52    <TR>
53<TD width="29%" valign="TOP"><FONT size="2">0x80200094</FONT></TD>
54<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>11</SUB></I></FONT></TD>
55<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[1][1]</FONT></TD>
56    </TR>
57    <TR>
58<TD width="29%" valign="TOP"><FONT size="2">0x80200098</FONT></TD>
59<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>12</SUB></I></FONT></TD>
60<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[1][2]</FONT></TD>
61    </TR>
62    <TR>
63<TD width="29%" valign="TOP"><FONT size="2">0x8020009c</FONT></TD>
64<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>13</SUB></I></FONT></TD>
65<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[1][3]</FONT></TD>
66    </TR>
67    <TR>
68<TD width="29%" valign="TOP"><FONT size="2">0x802000a0</FONT></TD>
69<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>20</SUB></I></FONT></TD>
70<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[2][0]</FONT></TD>
71    </TR>
72    <TR>
73<TD width="29%" valign="TOP"><FONT size="2">0x802000a4</FONT></TD>
74<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>21</SUB></I></FONT></TD>
75<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[2][1]</FONT></TD>
76    </TR>
77    <TR>
78<TD width="29%" valign="TOP"><FONT size="2">0x802000a8</FONT></TD>
79<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>22</SUB></I></FONT></TD>
80<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[2][2]</FONT></TD>
81    </TR>
82    <TR>
83<TD width="29%" valign="TOP"><FONT size="2">0x802000ac</FONT></TD>
84<TD width="31%" valign="TOP"><FONT size="2"><I>m<SUB>23</SUB></I></FONT></TD>
85<TD width="40%" valign="TOP"><FONT face="Courier New" size="2">m[2][3]</FONT></TD>
86    </TR>
87  </TBODY>
88</TABLE>
89</CENTER>
90</DIV>
91<P><B>Note:</B> Storage format is transparent to the programmer if matrices are set and manipulated exclusively by <EM><STRONG><code>MTX</code></STRONG></EM> functions, but <EM>it</EM> is relevant if matrix elements are set individually.&nbsp;To insulate code from future changes to the storage format, do not set matrix values by hand, and do not initialize matrices when they are first declared. Instead, use the macro <a href="../general/MTXRowCol.html"><code>MTXRowCol(m,row,col)</code></a> defined in <code>mtx.h</code>.</P>
92<P>An <EM><CODE><strong>Mtx</strong></CODE></EM> is row-major for computational purposes, e.g., to apply a rotation (<STRONG><EM><CODE>mR</CODE></EM></STRONG>) followed by a translation (<STRONG><EM><CODE>mT</CODE></EM></STRONG>) to a point (<EM><CODE><STRONG>pOld</STRONG></CODE></EM>):&nbsp; <CODE>pNew = mT x mR x pOld</CODE>.&nbsp;If programmed, this appears as shown below.</P>
93<BLOCKQUOTE><CODE>MTXConcat( mT, mR, mFinal );</CODE><BR> <CODE>MTXMultVec( mFinal, &amp;pOld, &amp;pNew );</CODE></BLOCKQUOTE>
94<P>An <EM><CODE><strong>MtxPtr</strong></CODE></EM> is a pointer to an array of four floats. <EM><CODE><strong>MtxPtr</strong></CODE></EM> is also a pointer to <EM><CODE><strong>Mtx</strong></CODE></EM> and can replace <EM><CODE><strong>Mtx</strong></CODE></EM> as a function argument. It's even possible to use subscripts just as with <EM><CODE><strong>Mtx</strong></CODE></EM>. However, it's really a pointer to an array of four floats.&nbsp;This has two implications.&nbsp;First, an <EM><CODE><strong>MtxPtr</strong></CODE></EM> is assigned to an <EM><CODE><strong>Mtx</strong></CODE></EM> without the use of the <CODE>&amp;</CODE> operator.&nbsp;For example: </P>
95<BLOCKQUOTE><CODE>void foo( Mtx m1, Mtx m2 )<BR> {<BR> &nbsp;&nbsp;&nbsp; MtxPtr mPtr;</CODE> <BR> <CODE> &nbsp; &nbsp;if( condition )<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPtr = m1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// note that the &amp; operator is not required.<BR> &nbsp;&nbsp;&nbsp; else<BR> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mPtr = m2;</CODE> <CODE>&nbsp;&nbsp;&nbsp; MTXIdentity( mPtr );<BR> }</CODE></BLOCKQUOTE>
96<P>Second, you cannot just increment and decrement an <EM><CODE><strong>MtxPtr</strong></CODE></EM>, because its size is 16, not 48.&nbsp;Therefore, we have defined a constant in <code>mtx.h</code> which provides the correct multiplier to offset a <EM><CODE><strong>MtxPtr</strong></CODE></EM> by the size of one matrix:</P>
97<BLOCKQUOTE><CODE>#define MTX_PTR_OFFSET&nbsp;&nbsp; 3</CODE></BLOCKQUOTE>
98<P>Use <code>MTX_PTR_OFFSET</code> whenever you need to increment an <EM><CODE><strong>MtxPtr</strong></CODE></EM> to the next matrix of an array.&nbsp;This will insulate your code from future changes to the <EM><CODE><strong>Mtx</strong></CODE></EM> storage format. For example: </P>
99<BLOCKQUOTE><CODE>Mtx mArray[2];<BR> MtxPtr mPtr;<BR></CODE><BR> <CODE>mPtr = (MtxPtr)mArray; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// mPtr points to mArray[0]<BR> MTXIdentity( mPtr ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// set mArray[0] to an identity matrix<BR> mPtr += MTX_PTR_OFFSET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // mPtr now points to mArray[1]<BR> MTXTrans( mPtr, 3.0, 4.0, 5.0 );&nbsp;&nbsp;// set mArray[1] to a translation matrix<BR></CODE></BLOCKQUOTE>
100<P>A function cannot return a pointer to a two-dimensional array, but it can return an <EM><CODE><strong>MtxPtr</strong></CODE></EM>.&nbsp;This makes <EM><CODE><strong>MtxPtr</strong></CODE></EM> especially useful for functions that need to return a matrix, For example, the following type of matrix stack function.</P>
101<BLOCKQUOTE><CODE>MtxPtr mPtr;<BR> MtxStack stack;<BR> Point3d pt = { 3.0, 4.0, 5.0 };</CODE><BR> <BR> <CODE>// + some code to initialize stack</CODE><BR> <CODE>mPtr = GetStackPtr( &amp;stack );</CODE><BR> <CODE>MTXMultVec( mPtr, &amp;pt, &amp;pt );</CODE>
102</BLOCKQUOTE>
103
104<H2 align="left">See Also</H2>
105<P>
106<A href="Mtx44_Mtx44Ptr.html"><CODE>Mtx44, Mtx44Ptr</CODE></A>, <A href="../stack/MTXAllocStack.html"><CODE>MTXAllocStack</CODE></A>, <A href="../general/MTXConcat.html"><CODE>MTXConcat</CODE></A>, <A href="../general/MTXCopy.html"><CODE>MTXCopy</CODE></A>, <A href="../stack/MTXFreeStack.html"><CODE>MTXFreeStack</CODE></A>, <A href="../stack/MTXGetStackPtr.html"><CODE>MTXGetStackPtr</CODE></A>, <A href="../general/MTXIdentity.html"><CODE>MTXIdentity</CODE></A>, <A href="../stack/MTXInitStack.html"><CODE>MTXInitStack</CODE></A>, <A href="../general/MTXInverse.html"><CODE>MTXInverse</CODE></A>, <A href="../view/MTXLookAt.html"><CODE>MTXLookAt</CODE></A>, <A href="../general/MTXMultVec.html"><CODE>MTXMultVec</CODE></A>, <A href="../general/MTXMultVecArray.html"><CODE>MTXMultVecArray</CODE></A>, <A href="../stack/MTXPop.html"><CODE>MTXPop</CODE></A>, <A href="../stack/MTXPush.html"><CODE>MTXPush</CODE></A>, <A href="../stack/MTXPushFwd.html"><CODE>MTXPushFwd</CODE></A>, <A href="../stack/MTXPushInv.html"><CODE>MTXPushInv</CODE></A>, <A href="../stack/MTXPushInvXpose.html"><CODE>MTXPushInvXpose</CODE></A>, <A href="../model/MTXQuat.html"><CODE>MTXQuat</CODE></A>, <A href="../model/MTXRotAxisRad.html"><CODE>MTXRotAxis</CODE></A>, <A href="../model/MTXRotDeg.html"><CODE>MTXRotDeg</CODE></A>, <A href="../model/MTXRotTrig.html"><CODE>MTXRotTrig</CODE></A>, <A href="../general/MTXRowCol.html"><CODE>MTXRowCol</CODE></A>, <A href="../model/MTXScale.html"><CODE>MTXScale</CODE></A>, <A href="../model/MTXTrans.html"><CODE>MTXTrans</CODE></A>, <A href="../general/MTXTranspose.html"><CODE>MTXTranspose</CODE></A>
107</P>
108<H2>Revision History</H2>
109<P>03/01/2006 Initial version.</p>
110</BODY>
111</HTML>