220 lines
7.8 KiB
HTML
220 lines
7.8 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<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>
|
|
<meta name="chapter" content="52" />
|
|
<meta name="pages" content="975-977" />
|
|
</head>
|
|
|
|
<body>
|
|
<center>
|
|
<table border="1">
|
|
<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><b>LISTING 52.3 L52-3.C</b></p>
|
|
<pre>
|
|
/* Routines to perform incremental rotations around the three axes. */
|
|
|
|
#include <math.h>
|
|
#include “polygon.h”
|
|
|
|
/* 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>
|
|
|
|
<p><b>LISTING 52.4 L52-4.C</b></p>
|
|
<pre>
|
|
/* Fixed point matrix arithmetic functions. */
|
|
|
|
#include “polygon.h”
|
|
|
|
/* 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<3; 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<3; i++) {
|
|
for (j=0; j<4; 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>
|
|
|
|
<p><b>LISTING 52.5 L52-5.C</b></p>
|
|
<pre>
|
|
/* Set up basic data that needs to be in fixed point, to avoid data
|
|
definition hassles. */
|
|
|
|
#include “polygon.h”
|
|
|
|
/* 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<3; i++)
|
|
for (j=0; j<4; j++)
|
|
WorldViewXform[i][j] = INT_TO_FIXED(IntWorldViewXform[i][j]);
|
|
for (i=0; i<NUM_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>
|
|
|
|
<center>
|
|
<table border="1">
|
|
<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="noshade" />
|
|
|
|
<div align="center">
|
|
Graphics Programming Black Book © 2001 Michael Abrash
|
|
</div>
|
|
</body>
|
|
</html>
|