109 lines
5.9 KiB
Markdown
109 lines
5.9 KiB
Markdown
------------------------ --------------------------------- --------------------
|
||
[Previous](51-04.html) [Table of Contents](index.html) [Next](51-06.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
With the above optimizations, the sample program is certainly adequately
|
||
responsive on a 20 MHz 386 (sans 387; I’m sure it’s wonderfully
|
||
responsive with a math coprocessor). Still, it couldn’t quite keep up
|
||
with the keyboard when I modified it to read only one key each time
|
||
through the loop—and we’re talking about only eight vertices here. This
|
||
indicates that we’re already near the limit of animation complexity
|
||
possible with our current approach. It’s time to start rethinking that
|
||
approach; over two-thirds of the overall time is spent in floating-point
|
||
calculations, and it’s there that we’ll begin to attack the performance
|
||
bottleneck we find ourselves up against.
|
||
|
||
### Incremental Transformation {#Heading5}
|
||
|
||
Listing 51.4 contains three functions; each concatenates an additional
|
||
rotation around one of the three axes to an existing rotation. To
|
||
improve performance, only the matrix entries that are affected in a
|
||
rotation around each particular axis are recalculated (all but four of
|
||
the entries in a single-axis rotation matrix are either 0 or 1, as shown
|
||
in Chapter 50). This cuts the number of floating-point multiplies from
|
||
the 64 required for the multiplication of two 4x4 matrices to just 12,
|
||
and floating point adds from 48 to 6.
|
||
|
||
Be aware that Listing 51.4 performs an incremental rotation on top of
|
||
whatever rotation is already in the matrix. The cube may already have
|
||
been turned left, right, up, down, and sideways; regardless, Listing
|
||
51.4 just tacks the specified rotation onto whatever already exists. In
|
||
this way, the object-to-world transformation matrix contains a history
|
||
of all the rotations ever specified by the user, concatenated one after
|
||
another onto the original matrix. Potential loss of precision is a
|
||
problem associated with using such an approach to represent a very long
|
||
concatenation of transformations, especially with fixed-point
|
||
arithmetic; that’s not a problem for us yet, but we’ll run into it
|
||
eventually.
|
||
|
||
**LISTING 51.4 L51-4.C**
|
||
|
||
/* 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 the transformation in
|
||
XformToChange, placing result back in XformToChange. */
|
||
void AppendRotationX(double XformToChange[4][4], double Angle)
|
||
{
|
||
double Temp10, Temp11, Temp12, Temp20, Temp21, Temp22;
|
||
double CosTemp = cos(Angle), SinTemp = sin(Angle);
|
||
/* Calculate the new values of the four affected matrix entries */
|
||
Temp10 = CosTemp*XformToChange[1][0]+ -SinTemp*XformToChange[2][0];
|
||
Temp11 = CosTemp*XformToChange[1][1]+ -SinTemp*XformToChange[2][1];
|
||
Temp12 = CosTemp*XformToChange[1][2]+ -SinTemp*XformToChange[2][2];
|
||
Temp20 = SinTemp*XformToChange[1][0]+ CosTemp*XformToChange[2][0];
|
||
Temp21 = SinTemp*XformToChange[1][1]+ CosTemp*XformToChange[2][1];
|
||
Temp22 = SinTemp*XformToChange[1][2]+ 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 the transformation in
|
||
XformToChange, placing result back in XformToChange. */
|
||
void AppendRotationY(double XformToChange[4][4], double Angle)
|
||
{
|
||
double Temp00, Temp01, Temp02, Temp20, Temp21, Temp22;
|
||
double CosTemp = cos(Angle), SinTemp = sin(Angle);
|
||
|
||
/* Calculate the new values of the four affected matrix entries */
|
||
Temp00 = CosTemp*XformToChange[0][0]+ SinTemp*XformToChange[2][0];
|
||
Temp01 = CosTemp*XformToChange[0][1]+ SinTemp*XformToChange[2][1];
|
||
Temp02 = CosTemp*XformToChange[0][2]+ SinTemp*XformToChange[2][2];
|
||
Temp20 = -SinTemp*XformToChange[0][0]+ CosTemp*XformToChange[2][0];
|
||
Temp21 = -SinTemp*XformToChange[0][1]+ CosTemp*XformToChange[2][1];
|
||
Temp22 = -SinTemp*XformToChange[0][2]+ 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 the transformation in
|
||
XformToChange, placing result back in XformToChange. */
|
||
void AppendRotationZ(double XformToChange[4][4], double Angle)
|
||
{
|
||
double Temp00, Temp01, Temp02, Temp10, Temp11, Temp12;
|
||
double CosTemp = cos(Angle), SinTemp = sin(Angle);
|
||
/* Calculate the new values of the four affected matrix entries */
|
||
Temp00 = CosTemp*XformToChange[0][0]+ -SinTemp*XformToChange[1][0];
|
||
Temp01 = CosTemp*XformToChange[0][1]+ -SinTemp*XformToChange[1][1];
|
||
Temp02 = CosTemp*XformToChange[0][2]+ -SinTemp*XformToChange[1][2];
|
||
Temp10 = SinTemp*XformToChange[0][0]+ CosTemp*XformToChange[1][0];
|
||
Temp11 = SinTemp*XformToChange[0][1]+ CosTemp*XformToChange[1][1];
|
||
Temp12 = SinTemp*XformToChange[0][2]+ 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;
|
||
}
|
||
|
||
------------------------ --------------------------------- --------------------
|
||
[Previous](51-04.html) [Table of Contents](index.html) [Next](51-06.html)
|
||
------------------------ --------------------------------- --------------------
|
||
|
||
* * * * *
|
||
|
||
Graphics Programming Black Book © 2001 Michael Abrash
|