**LISTING 52.6 L52-6.C** /* Rotates and moves a polygon-based object around the three axes. Movement is implemented only along the Z axis currently. */ #include "polygon.h" void RotateAndMovePObject(PObject * ObjectToMove) { if (--ObjectToMove->RDelayCount == 0) { /* rotate */ ObjectToMove->RDelayCount = ObjectToMove->RDelayCountBase; if (ObjectToMove->Rotate.RotateX != 0.0) AppendRotationX(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateX); if (ObjectToMove->Rotate.RotateY != 0.0) AppendRotationY(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateY); if (ObjectToMove->Rotate.RotateZ != 0.0) AppendRotationZ(ObjectToMove->XformToWorld, ObjectToMove->Rotate.RotateZ); ObjectToMove->RecalcXform = 1; } /* Move in Z, checking for bouncing and stopping */ if (--ObjectToMove->MDelayCount == 0) { ObjectToMove->MDelayCount = ObjectToMove->MDelayCountBase; ObjectToMove->XformToWorld[2][3] += ObjectToMove->Move.MoveZ; if (ObjectToMove->XformToWorld[2][3]>ObjectToMove->Move.MaxZ) ObjectToMove->Move.MoveZ = 0; /* stop if close enough */ ObjectToMove->RecalcXform = 1; } } **LISTING 52.7 L52-7.C** /* Draws all visible faces in specified polygon-based object. Object must have previously been transformed and projected, so that ScreenVertexList array is filled in. */ #include "polygon.h" void DrawPObject(PObject * ObjectToXform) { int i, j, NumFaces = ObjectToXform->NumFaces, NumVertices; int * VertNumsPtr; Face * FacePtr = ObjectToXform->FaceList; Point * ScreenPoints = ObjectToXform->ScreenVertexList; long v1, v2, w1, w2; Point Vertices[MAX_POLY_LENGTH]; PointListHeader Polygon; /* Draw each visible face (polygon) of the object in turn */ for (i=0; iNumVerts; /* Copy over the face's vertices from the vertex list */ for (j=0, VertNumsPtr=FacePtr->VertNums; j 0) { /* It is facing the screen, so draw */ /* Appropriately adjust the extent of the rectangle used to erase this object later */ for (j=0; j ObjectToXform->EraseRect[NonDisplayedPage].Right) if (Vertices[j].X < SCREEN_WIDTH) ObjectToXform->EraseRect[NonDisplayedPage].Right = Vertices[j].X; else ObjectToXform->EraseRect[NonDisplayedPage].Right = SCREEN_WIDTH; if (Vertices[j].Y > ObjectToXform->EraseRect[NonDisplayedPage].Bottom) if (Vertices[j].Y < SCREEN_HEIGHT) ObjectToXform->EraseRect[NonDisplayedPage].Bottom = Vertices[j].Y; else ObjectToXform->EraseRect[NonDisplayedPage].Bottom= SCREEN_HEIGHT; if (Vertices[j].X < ObjectToXform->EraseRect[NonDisplayedPage].Left) if (Vertices[j].X > 0) ObjectToXform->EraseRect[NonDisplayedPage].Left = Vertices[j].X; else ObjectToXform->EraseRect[NonDisplayedPage].Left=0; if (Vertices[j].Y < ObjectToXform->EraseRect[NonDisplayedPage].Top) if (Vertices[j].Y > 0) ObjectToXform->EraseRect[NonDisplayedPage].Top = Vertices[j].Y; else ObjectToXform->EraseRect[NonDisplayedPage].Top=0; } /* Draw the polygon */ DRAW_POLYGON(Vertices, NumVertices, FacePtr->Color, 0, 0); } } }