home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / 3dgraph / c / chap2_10.cpp next >
Encoding:
C/C++ Source or Header  |  1996-03-19  |  7.7 KB  |  299 lines

  1. // chap2_10.cpp;
  2.  
  3. #include <iostream.h>
  4. #include <graphics.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <conio.h>
  9.  
  10. #define PI 3.141592654
  11.  
  12.  
  13. const xoffset=640/2;
  14. const yoffset=480/2;
  15. const xscale=1;
  16. const yscale=-1;
  17. const persp=500;
  18.  
  19. struct point
  20. {
  21.     float xw, yw, zw;
  22.     int   xs, ys, zs;
  23. }   vertex[18];
  24.  
  25. typedef float  matrix_4x4[4][4];
  26. int    edges[27][27];
  27. FILE   *fp;
  28. int    c, hither=600;
  29. char   ch;
  30. matrix_4x4   w2v, temp, temp2;
  31.  
  32. void initialise_graphics()
  33. {
  34.      int gdriver=DETECT, gmode, errorcode;
  35.  
  36.      initgraph(&gdriver, &gmode,"");
  37.      errorcode=graphresult();
  38.      if (errorcode!=grOk)
  39.      {
  40.       printf("Graphics Error: %s\n",grapherrormsg(errorcode));
  41.       printf("Program Aborted \n");
  42.       exit(1);
  43.      }
  44.      setlinestyle(0,0,3);
  45.      setcolor(WHITE);
  46.  
  47. }
  48.  
  49. void translate(float x, float y, float z, matrix_4x4 m)
  50. {
  51.      m[0][0]=1; m[1][0]=0; m[2][0]=0; m[3][0]=0;
  52.      m[0][1]=0; m[1][1]=1; m[2][1]=0; m[3][1]=0;
  53.      m[0][2]=0; m[1][2]=0; m[2][2]=1; m[3][2]=0;
  54.      m[0][3]=x; m[1][3]=y; m[2][3]=z; m[3][3]=1;
  55. };
  56.  
  57. void rotate_x(float t, matrix_4x4 m)
  58. {
  59.      m[0][0]=1; m[1][0]=0;       m[2][0]=0;      m[3][0]=0;
  60.      m[0][1]=0; m[1][1]=cos(t);  m[2][1]=sin(t); m[3][1]=0;
  61.      m[0][2]=0; m[1][2]=-sin(t); m[2][2]=cos(t); m[3][2]=0;
  62.      m[0][3]=0; m[1][3]=0;       m[2][3]=0;      m[3][3]=1;
  63. };
  64.  
  65.  
  66. void rotate_y(float t, matrix_4x4 m)
  67. {
  68.      m[0][0]=cos(t); m[1][0]=0; m[2][0]=-sin(t); m[3][0]=0;
  69.      m[0][1]=0;      m[1][1]=1; m[2][1]=0;       m[3][1]=0;
  70.      m[0][2]=sin(t); m[1][2]=0; m[2][2]=cos(t);  m[3][2]=0;
  71.      m[0][3]=0;      m[1][3]=0; m[2][3]=0;       m[3][3]=1;
  72. };
  73.  
  74. void rotate_z(float t, matrix_4x4 m)
  75. {
  76.      m[0][0]=cos(t);  m[1][0]=sin(t); m[2][0]=0; m[3][0]=0;
  77.      m[0][1]=-sin(t); m[1][1]=cos(t); m[2][1]=0; m[3][1]=0;
  78.      m[0][2]=0;       m[1][2]=0;      m[2][2]=1; m[3][2]=0;
  79.      m[0][3]=0;       m[1][3]=0;      m[2][3]=0; m[3][3]=1;
  80. };
  81.  
  82. void copy_4x4(matrix_4x4 in, matrix_4x4 out)
  83. {
  84.       int c, r;
  85.       for (r=0; r<4; r++)
  86.       for (c=0; c<4; c++)
  87.           out[r][c]=in[r][c];
  88. }
  89.  
  90. void mult_4x4(matrix_4x4 a, matrix_4x4 b, matrix_4x4 m)
  91. {
  92.       int c;
  93.       for (c=0; c<4; c++)
  94.       m[c][0]=a[0][0]*b[c][0]+a[1][0]*b[c][1]+a[2][0]*b[c][2]+a[3][0]*b[c][3];
  95.       for (c=0; c<4; c++)
  96.       m[c][1]=a[0][1]*b[c][0]+a[1][1]*b[c][1]+a[2][1]*b[c][2]+a[3][1]*b[c][3];
  97.       for (c=0; c<4; c++)
  98.       m[c][2]=a[0][2]*b[c][0]+a[1][2]*b[c][1]+a[2][2]*b[c][2]+a[3][2]*b[c][3];
  99.       for (c=0; c<4; c++)
  100.       m[c][3]=a[0][3]*b[c][0]+a[1][3]*b[c][1]+a[2][3]*b[c][2]+a[3][3]*b[c][3];
  101. };
  102.  
  103.  
  104. void draw_picture()
  105. {
  106.      int x1,y1,z1,x2,y2,z2,c;
  107.      cleardevice();
  108.      for (c=0; c<27; c++)
  109.      {
  110.       x1=vertex[edges[c][0]].xs;
  111.       y1=vertex[edges[c][0]].ys;
  112.       z1=vertex[edges[c][0]].zs;
  113.       x2=vertex[edges[c][1]].xs;
  114.       y2=vertex[edges[c][1]].ys;
  115.       z2=vertex[edges[c][1]].zs;
  116.       if ((z2>hither)||(z1>hither))
  117.       {
  118.            if (z1<hither)
  119.            {
  120.             x1=x1+(x2-x1)*(float(hither-z1)/float(z2-z1));
  121.             y1=y1+(y2-y1)*(float(hither-z1)/float(z2-z1));
  122.             z1=hither;
  123.            };
  124.            if (z2<hither)
  125.            {
  126.             x2=x2+(x1-x2)*(float(hither-z2)/float(z1-z2));
  127.             y2=y2+(y1-y2)*(float(hither-z2)/float(z1-z2));
  128.             z2=hither;
  129.            };
  130.            line(x1,y1,x2,y2);
  131.       };
  132.      };
  133. };
  134.  
  135. void transform(matrix_4x4 m)
  136. {
  137.      int c;
  138.      for (c=0; c<18; c++)
  139.      {
  140.      vertex[c].zs=(vertex[c].xw*m[2][0]+vertex[c].yw*m[2][1]+vertex[c].zw*m[2][2]+m[2][3]);
  141.      vertex[c].xs=(((vertex[c].xw*m[0][0]+vertex[c].yw*m[0][1]+vertex[c].zw*m[0][2]+m[0][3])
  142.                *(persp/float(vertex[c].zs))*xscale)+xoffset);
  143.      vertex[c].ys=(((vertex[c].xw*m[1][0]+vertex[c].yw*m[1][1]+vertex[c].zw*m[1][2]+m[1][3])
  144.                *(persp/float(vertex[c].zs))*yscale)+yoffset);
  145.      };
  146. };
  147.  
  148. void main()
  149. {
  150.      clrscr();
  151.      printf("\n"); printf("\n"); printf("\n");
  152.      printf("This is from Chapter 2 Step 10 of the Virtual Reality Homebrewer\'s Handbook, \n");
  153.      printf("and shows how to move around a virtual shape drawn in wireframe, clipped to \n");
  154.      printf("the hither plane. \n");
  155.      printf("\n");
  156.      printf("To show the effect of clipping, the hither plane is almost at the object. \n");
  157.      printf("Move it back if you just want to move around - or the object will disappear! \n");
  158.      printf("\n");
  159.      printf("\n");
  160.      printf("Controls:       8/2  - move forwards/back \n");
  161.      printf("                4/6  - move left/back \n");
  162.      printf("                7/1  - move up/down \n");
  163.      printf("                o/l  - pitch up/down \n");
  164.      printf("                </>  - yaw left/right \n");
  165.      printf("                n/m  - roll left/right \n");
  166.      printf("                =/-  - move hither plane forwards/back \n");
  167.      printf("\n");
  168.      printf("                q    - quit \n");
  169.      printf("\n");
  170.      printf("                Press any key to continue \n");
  171.      ch=getch();
  172.  
  173.  
  174.  
  175. //   Read in vertex data
  176.      if ((fp=fopen("points.dat","r"))==NULL)
  177.      {
  178.       puts("Can't open points.dat");
  179.       exit(0);
  180.      }
  181.      for (c=0; c<18; c++)
  182.      {
  183.       fscanf(fp,"%f %f %f \n",&vertex[c].xw,&vertex[c].yw,&vertex[c].zw);
  184.      }
  185.      fclose(fp);
  186. //   Move to z=500
  187.      for (c=0; c<18; c++)
  188.       vertex[c].zw=vertex[c].zw+500;
  189.  
  190. //   Read in edge data
  191.      if ((fp=fopen("edges.dat","r"))==NULL)
  192.      {
  193.       puts("Can't open edges.dat");
  194.       exit(0);
  195.      }
  196.      for (c=0; c<27; c++)
  197.       fscanf(fp,"%d %d \n",&edges[c][0],&edges[c][1]);
  198.      fclose(fp);
  199.      for (c=0; c<27; c++)
  200.      {
  201.       edges[c][0]--; edges[c][1]--;
  202.      }
  203.  
  204.      initialise_graphics();
  205.  
  206.      translate(-500,-400,0,w2v);
  207.      rotate_y(PI/5,temp);
  208.      mult_4x4(w2v,temp,temp2);
  209.      rotate_x(-PI/6,temp);
  210.      mult_4x4(temp2,temp,w2v);
  211.  
  212.      transform(w2v);
  213.      draw_picture();
  214.      do
  215.      {
  216.        ch=getch();
  217.        switch (ch)
  218.        {
  219.        case '8': {
  220.                translate(0,0,-10,temp);
  221.                mult_4x4(w2v,temp,temp2);
  222.                copy_4x4(temp2,w2v);
  223.                break;
  224.              };
  225.        case    '2': {
  226.                translate(0,0,10,temp);
  227.                mult_4x4(w2v,temp,temp2);
  228.                copy_4x4(temp2,w2v);
  229.                break;
  230.              };
  231.        case    '4': {
  232.                translate(10,0,0,temp);
  233.                mult_4x4(w2v,temp,temp2);
  234.                copy_4x4(temp2,w2v);
  235.                break;
  236.              };
  237.        case    '6': {
  238.                translate(-10,0,0,temp);
  239.                mult_4x4(w2v,temp,temp2);
  240.                copy_4x4(temp2,w2v);
  241.                break;
  242.              };
  243.        case    '1': {
  244.                translate(0,10,0,temp);
  245.                mult_4x4(w2v,temp,temp2);
  246.                copy_4x4(temp2,w2v);
  247.                break;
  248.              };
  249.        case    '7': {
  250.                translate(0,-10,0,temp);
  251.                mult_4x4(w2v,temp,temp2);
  252.                copy_4x4(temp2,w2v);
  253.                break;
  254.              };
  255.        case    ',': {
  256.                rotate_y(PI/180.0,temp);
  257.                mult_4x4(w2v,temp,temp2);
  258.                copy_4x4(temp2,w2v);
  259.                break;
  260.              };
  261.        case    '.': {
  262.                rotate_y(-PI/180.0,temp);
  263.                mult_4x4(w2v,temp,temp2);
  264.                copy_4x4(temp2,w2v);
  265.                break;
  266.              };
  267.        case    'm': {
  268.                rotate_z(PI/180.0,temp);
  269.                mult_4x4(w2v,temp,temp2);
  270.                copy_4x4(temp2,w2v);
  271.                break;
  272.              };
  273.        case    'n': {
  274.                rotate_z(-PI/180.0,temp);
  275.                mult_4x4(w2v,temp,temp2);
  276.                copy_4x4(temp2,w2v);
  277.                break;
  278.              };
  279.        case    'o': {
  280.                rotate_x(PI/180.0,temp);
  281.                mult_4x4(w2v,temp,temp2);
  282.                copy_4x4(temp2,w2v);
  283.                break;
  284.              };
  285.        case    'l': {
  286.                rotate_x(-PI/180.0,temp);
  287.                mult_4x4(w2v,temp,temp2);
  288.                copy_4x4(temp2,w2v);
  289.                break;
  290.              };
  291.        case    '=': hither=hither+10; break;
  292.        case    '-': hither=hither-10; break;
  293.        };
  294.        transform(w2v);
  295.        draw_picture();
  296.      }
  297.      while (ch!='q');
  298.      closegraph();
  299. }