abrash-black-book/52-03.html
2013-12-30 12:21:49 +11:00

228 lines
8.3 KiB
HTML

<HTML>
<HEAD>
<META name=vsisbn content="1576101746">
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
<META name=vsauthor content="Michael Abrash">
<META name=vspublisher content="The Coriolis Group">
<META name=vspubdate content="07/01/97">
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Fast 3-D Animation: Meet X-Sharp</TITLE>
<!-- HEADER -->
<!-- Empty Reference Subhead -->
<!--ISBN=1576101746//-->
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
<!--AUTHOR=Michael Abrash//-->
<!--PUBLISHER=The Coriolis Group, Inc.//-->
<!--CHAPTER=52//-->
<!--PAGES=975-977//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="52-02.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="52-04.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P><B>LISTING 52.3 L52-3.C</B></P>
<!-- CODE //-->
<PRE>
/* Routines to perform incremental rotations around the three axes. */
#include &ltmath.h&gt
#include &#147;polygon.h&#148;
/* Concatenate a rotation by Angle around the X axis to transformation in
XformToChange, placing the result back into XformToChange. */
void AppendRotationX(Xform XformToChange, double Angle)
{
Fixedpoint Temp10, Temp11, Temp12, Temp20, Temp21, Temp22;
Fixedpoint CosTemp = DOUBLE_TO_FIXED(cos(Angle));
Fixedpoint SinTemp = DOUBLE_TO_FIXED(sin(Angle));
/* Calculate the new values of the six affected matrix entries */
Temp10 = FixedMul(CosTemp, XformToChange[1][0]) +
FixedMul(-SinTemp, XformToChange[2][0]);
Temp11 = FixedMul(CosTemp, XformToChange[1][1]) +
FixedMul(-SinTemp, XformToChange[2][1]);
Temp12 = FixedMul(CosTemp, XformToChange[1][2]) +
FixedMul(-SinTemp, XformToChange[2][2]);
Temp20 = FixedMul(SinTemp, XformToChange[1][0]) +
FixedMul(CosTemp, XformToChange[2][0]);
Temp21 = FixedMul(SinTemp, XformToChange[1][1]) +
FixedMul(CosTemp, XformToChange[2][1]);
Temp22 = FixedMul(SinTemp, XformToChange[1][2]) +
FixedMul(CosTemp, XformToChange[2][2]);
/* Put the results back into XformToChange */
XformToChange[1][0] = Temp10; XformToChange[1][1] = Temp11;
XformToChange[1][2] = Temp12; XformToChange[2][0] = Temp20;
XformToChange[2][1] = Temp21; XformToChange[2][2] = Temp22;
}
/* Concatenate a rotation by Angle around the Y axis to transformation in
XformToChange, placing the result back into XformToChange. */
void AppendRotationY(Xform XformToChange, double Angle)
{
Fixedpoint Temp00, Temp01, Temp02, Temp20, Temp21, Temp22;
Fixedpoint CosTemp = DOUBLE_TO_FIXED(cos(Angle));
Fixedpoint SinTemp = DOUBLE_TO_FIXED(sin(Angle));
/* Calculate the new values of the six affected matrix entries */
Temp00 = FixedMul(CosTemp, XformToChange[0][0]) +
FixedMul(SinTemp, XformToChange[2][0]);
Temp01 = FixedMul(CosTemp, XformToChange[0][1]) +
FixedMul(SinTemp, XformToChange[2][1]);
Temp02 = FixedMul(CosTemp, XformToChange[0][2]) +
FixedMul(SinTemp, XformToChange[2][2]);
Temp20 = FixedMul(-SinTemp, XformToChange[0][0]) +
FixedMul( CosTemp, XformToChange[2][0]);
Temp21 = FixedMul(-SinTemp, XformToChange[0][1]) +
FixedMul(CosTemp, XformToChange[2][1]);
Temp22 = FixedMul(-SinTemp, XformToChange[0][2]) +
FixedMul(CosTemp, XformToChange[2][2]);
/* Put the results back into XformToChange */
XformToChange[0][0] = Temp00; XformToChange[0][1] = Temp01;
XformToChange[0][2] = Temp02; XformToChange[2][0] = Temp20;
XformToChange[2][1] = Temp21; XformToChange[2][2] = Temp22;
}
/* Concatenate a rotation by Angle around the Z axis to transformation in
XformToChange, placing the result back into XformToChange. */
void AppendRotationZ(Xform XformToChange, double Angle)
{
Fixedpoint Temp00, Temp01, Temp02, Temp10, Temp11, Temp12;
Fixedpoint CosTemp = DOUBLE_TO_FIXED(cos(Angle));
Fixedpoint SinTemp = DOUBLE_TO_FIXED(sin(Angle));
/* Calculate the new values of the six affected matrix entries */
Temp00 = FixedMul(CosTemp, XformToChange[0][0]) +
FixedMul(-SinTemp, XformToChange[1][0]);
Temp01 = FixedMul(CosTemp, XformToChange[0][1]) +
FixedMul(-SinTemp, XformToChange[1][1]);
Temp02 = FixedMul(CosTemp, XformToChange[0][2]) +
FixedMul(-SinTemp, XformToChange[1][2]);
Temp10 = FixedMul(SinTemp, XformToChange[0][0]) +
FixedMul(CosTemp, XformToChange[1][0]);
Temp11 = FixedMul(SinTemp, XformToChange[0][1]) +
FixedMul(CosTemp, XformToChange[1][1]);
Temp12 = FixedMul(SinTemp, XformToChange[0][2]) +
FixedMul(CosTemp, XformToChange[1][2]);
/* Put the results back into XformToChange */
XformToChange[0][0] = Temp00; XformToChange[0][1] = Temp01;
XformToChange[0][2] = Temp02; XformToChange[1][0] = Temp10;
XformToChange[1][1] = Temp11; XformToChange[1][2] = Temp12;
}
</PRE>
<!-- END CODE //-->
<P><B>LISTING 52.4 L52-4.C</B></P>
<!-- CODE //-->
<PRE>
/* Fixed point matrix arithmetic functions. */
#include &#147;polygon.h&#148;
/* Matrix multiplies Xform by SourceVec, and stores the result in DestVec.
Multiplies a 4x4 matrix times a 4x1 matrix; the result is a 4x1 matrix. Cheats
by assuming the W coord is 1 and bottom row of matrix is 0 0 0 1, and doesn't
bother to set the W coordinate of the destination. */
void XformVec(Xform WorkingXform, Fixedpoint *SourceVec,
Fixedpoint *DestVec)
{
int i;
for (i=0; i&lt3; i++)
DestVec[i] = FixedMul(WorkingXform[i][0], SourceVec[0]) +
FixedMul(WorkingXform[i][1], SourceVec[1]) +
FixedMul(WorkingXform[i][2], SourceVec[2]) +
WorkingXform[i][3]; /* no need to multiply by W = 1 */
}
/* Matrix multiplies SourceXform1 by SourceXform2 and stores result in
DestXform. Multiplies a 4x4 matrix times a 4x4 matrix; result is a 4x4 matrix.
Cheats by assuming bottom row of each matrix is 0 0 0 1, and doesn't bother
to set the bottom row of the destination. */
void ConcatXforms(Xform SourceXform1, Xform SourceXform2,
Xform DestXform)
{
int i, j;
for (i=0; i&lt3; i++) {
for (j=0; j&lt4; j++)
DestXform[i][j] =
FixedMul(SourceXform1[i][0], SourceXform2[0][j]) +
FixedMul(SourceXform1[i][1], SourceXform2[1][j]) +
FixedMul(SourceXform1[i][2], SourceXform2[2][j]) +
SourceXform1[i][3];
}
}
</PRE>
<!-- END CODE //-->
<P><B>LISTING 52.5 L52-5.C</B></P>
<!-- CODE //-->
<PRE>
/* Set up basic data that needs to be in fixed point, to avoid data
definition hassles. */
#include &#147;polygon.h&#148;
/* All vertices in the basic cube */
static IntPoint3 IntCubeVerts[NUM_CUBE_VERTS] = {
{15,15,15},{15,15,-15},{15,-15,15},{15,-15,-15},
{-15,15,15},{-15,15,-15},{-15,-15,15},{-15,-15,-15} };
/* Transformation from world space into view space (no transformation,
currently) */
static int IntWorldViewXform[3][4] = {
{1,0,0,0}, {0,1,0,0}, {0,0,1,0}};
void InitializeFixedPoint()
{
int i, j;
for (i=0; i&lt3; i++)
for (j=0; j&lt4; j++)
WorldViewXform[i][j] = INT_TO_FIXED(IntWorldViewXform[i][j]);
for (i=0; i&ltNUM_CUBE_VERTS; i++) {
CubeVerts[i].X = INT_TO_FIXED(IntCubeVerts[i].X);
CubeVerts[i].Y = INT_TO_FIXED(IntCubeVerts[i].Y);
CubeVerts[i].Z = INT_TO_FIXED(IntCubeVerts[i].Z);
}
}
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="52-02.html">Previous</A></TD>
<TD><A HREF="index.html">Table of Contents</A></TD>
<TD><A HREF="52-04.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<hr width="90%" size="1" noshade>
<div align="center">
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book &copy; 2001 Michael Abrash</font>
</div>
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
<!-- reference_subfoot = footer -->
<!-- reference_footer = subfoot -->
<!-- BEGIN SUB FOOTER -->
</BODY>
</HTML>
<!-- END FOOTER -->