home *** CD-ROM | disk | FTP | other *** search
- /* Author: David Oster after the
- * floating point Pascal program by Charles W. Grant
- *
- * Synopsis: The graphic functions for Teapot 3-D
- */
- #include "Graf3D.h"
- #include "teapot.h"
-
- Point3D Pt3ds[1+DUCKCOUNT];
-
- /* BlendVector - calculate Bezier spline values for parameter t
- */
- static void BlendVector(
- Pt3dPtr d0, Pt3dPtr d1, Pt3dPtr d2, Pt3dPtr d3, Fixed t, Pt3dPtr result){
-
- result->x =
- FixMul(FixMul(FixMul(d0->x,ONE-t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d1->x), t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d2->x), t), t),ONE-t) +
- FixMul(FixMul(FixMul(d3->x, t), t), t);
- result->y =
- FixMul(FixMul(FixMul(d0->y,ONE-t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d1->y), t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d2->y), t), t),ONE-t) +
- FixMul(FixMul(FixMul(d3->y, t), t), t);
- result->z =
- FixMul(FixMul(FixMul(d0->z,ONE-t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d1->z), t),ONE-t),ONE-t) +
- FixMul(FixMul(FixMul(FixMul(THREE,d2->z), t), t),ONE-t) +
- FixMul(FixMul(FixMul(d3->z, t), t), t);
- }
-
- /* DisplayCurve - find "steps"+1 points on the spline and
- * draw "steps" line segments
- */
- static void DisplayCurve(Pt3dPtr d0, Pt3dPtr d1, Pt3dPtr d2, Pt3dPtr d3, int steps){
- Fixed t;
- Fixed step;
- Fixed loopmax;
- Point3D temp;
-
- step = FixRatio(1, steps); /* 1/steps */
- t = step;
- /* loopmax = 1 + step/2 */
- loopmax = ONE + FixMul(step, HALF);
- MoveTo3D(d0->x, d0->y, d0->z); /* move to start of spline */
- while(t < loopmax){
- BlendVector(d0, d1, d2, d3, t, &temp);
- LineTo3D(temp.x, temp.y, temp.z);
- t += step;
- }
- OneEvent(); /* let the user choose from the menu */
- }
-
- /* DisplayPatch -
- */
- void DisplayPatch(Patch patch, int steps){
- Fixed t;
- Fixed step;
- Fixed loopmax;
- Point3D d0, d1, d2, d3;
-
- step = FixRatio(1, steps); /* 1/steps */
- *((long int *) &t) = 0L;
- /* loopmax = 1 + step/2 */
- loopmax = ONE + FixMul(step, HALF);
-
- while(t < loopmax){
- /* splines of constant U */
- BlendVector(&Pt3ds[patch[0][0]], &Pt3ds[patch[0][1]],
- &Pt3ds[patch[0][2]], &Pt3ds[patch[0][3]], t, &d0);
- BlendVector(&Pt3ds[patch[1][0]], &Pt3ds[patch[1][1]],
- &Pt3ds[patch[1][2]], &Pt3ds[patch[1][3]], t, &d1);
- BlendVector(&Pt3ds[patch[2][0]], &Pt3ds[patch[2][1]],
- &Pt3ds[patch[2][2]], &Pt3ds[patch[2][3]], t, &d2);
- BlendVector(&Pt3ds[patch[3][0]], &Pt3ds[patch[3][1]],
- &Pt3ds[patch[3][2]], &Pt3ds[patch[3][3]], t, &d3);
-
- DisplayCurve(&d0, &d1, &d2, &d3, steps);
- /* splines of constant V */
- BlendVector(&Pt3ds[patch[0][0]], &Pt3ds[patch[1][0]],
- &Pt3ds[patch[2][0]], &Pt3ds[patch[3][0]], t, &d0);
- BlendVector(&Pt3ds[patch[0][1]], &Pt3ds[patch[1][1]],
- &Pt3ds[patch[2][1]], &Pt3ds[patch[3][1]], t, &d1);
- BlendVector(&Pt3ds[patch[0][2]], &Pt3ds[patch[1][2]],
- &Pt3ds[patch[2][2]], &Pt3ds[patch[3][2]], t, &d2);
- BlendVector(&Pt3ds[patch[0][3]], &Pt3ds[patch[1][3]],
- &Pt3ds[patch[2][3]], &Pt3ds[patch[3][3]], t, &d3);
- DisplayCurve(&d0, &d1, &d2, &d3, steps);
-
- t += step;
- }
- }
-
- /* DisplayPatches - steps tells how much to divide up patches
- */
- void DisplayPatches(int steps){
- int i;
-
- for(i=0; i< PATCHCOUNT; i++){
- DisplayPatch(patches[i], steps);
- }
- }
-
- /* FloatToFixed - convert from float to fix
- * note this routine doesn't work in general.
- * it works here only because abs(fl) is always < 30
- * On the new roms X2Fix(float) does what you want
- */
- static Fixed FloatToFixed(float fl){
- return FixRatio( (int) (fl * 1000.0),1000);
- }
-
- /* FloatsToFixeds - convert an array from one type to the other
- */
- void FloatsToFixeds(register float *fl, Fixed *fi, int n){
- while(n-- > 0){
- *fi++ = FloatToFixed(*fl++);
- }
- }
-
- /*
- note: (Fixed) 8 is a number very near zero.
- */
- void BaseGrid(void){
- int i;
- Pattern savePattern;
-
- BlockMove((Ptr) &thePort->pnPat, (Ptr) &savePattern, sizeof(Pattern));
- PenPat(&dkGray);
- PenSize(2,2);
- for(i = -10;i<=10;i++){
- MoveTo3D(FixRatio(i, 4), FixRatio(-10, 4), -(Fixed) 8);
- LineTo3D(FixRatio(i, 4), FixRatio(10, 4), -(Fixed) 8);
- }
- for(i = -10;i<=10;i++){
- MoveTo3D(FixRatio(-10, 4), FixRatio(i, 4), -(Fixed) 8);
- LineTo3D(FixRatio(10, 4), FixRatio(i, 4), -(Fixed) 8);
- }
- PenSize(1,1);
- PenPat(&savePattern);
- }
-