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

  1. // chap2_8.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;
  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 c;
  107.      cleardevice();
  108.      for (c=0; c<27; c++)
  109.       line(vertex[edges[c][0]].xs,vertex[edges[c][0]].ys,vertex[edges[c][1]].xs,vertex[edges[c][1]].ys);
  110. };
  111.  
  112. void transform(matrix_4x4 m)
  113. {
  114.      int c;
  115.      for (c=0; c<18; c++)
  116.      {
  117.      vertex[c].zs=(vertex[c].xw*m[2][0]+vertex[c].yw*m[2][1]+vertex[c].zw*m[2][2]+m[2][3]);
  118.      vertex[c].xs=(((vertex[c].xw*m[0][0]+vertex[c].yw*m[0][1]+vertex[c].zw*m[0][2]+m[0][3])
  119.                *(persp/float(vertex[c].zs))*xscale)+xoffset);
  120.      vertex[c].ys=(((vertex[c].xw*m[1][0]+vertex[c].yw*m[1][1]+vertex[c].zw*m[1][2]+m[1][3])
  121.                *(persp/float(vertex[c].zs))*yscale)+yoffset);
  122.      };
  123. };
  124.  
  125. void main()
  126. {
  127.      clrscr();
  128.      printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n");
  129.      printf("This is from Chapter 2 Step 8 of the Virtual Reality Homebrewer\'s Handbook \n");
  130.      printf("and shows how to move around a virtual shape drawn in wireframe. \n");
  131.      printf("\n");
  132.      printf("\n");
  133.      printf("Controls:       8/2  - move forwards/back \n");
  134.      printf("                4/6  - move left/back \n");
  135.      printf("                7/1  - move up/down \n");
  136.      printf("                o/l  - pitch up/down \n");
  137.      printf("                </>  - yaw left/right \n");
  138.      printf("                n/m  - roll left/right \n");
  139.      printf("\n");
  140.      printf("                q    - quit \n");
  141.      printf("\n");
  142.      printf("                Press any key to continue \n");
  143.      ch=getch();
  144.  
  145.  
  146.  
  147. //   Read in vertex data
  148.      if ((fp=fopen("points.dat","r"))==NULL)
  149.      {
  150.       puts("Can't open points.dat");
  151.       exit(0);
  152.      }
  153.      for (c=0; c<18; c++)
  154.      {
  155.       fscanf(fp,"%f %f %f \n",&vertex[c].xw,&vertex[c].yw,&vertex[c].zw);
  156.      }
  157.      fclose(fp);
  158. //   Move to z=500
  159.      for (c=0; c<18; c++)
  160.       vertex[c].zw=vertex[c].zw+500;
  161.  
  162. //   Read in edge data
  163.      if ((fp=fopen("edges.dat","r"))==NULL)
  164.      {
  165.       puts("Can't open edges.dat");
  166.       exit(0);
  167.      }
  168.      for (c=0; c<27; c++)
  169.       fscanf(fp,"%d %d \n",&edges[c][0],&edges[c][1]);
  170.      fclose(fp);
  171.      for (c=0; c<27; c++)
  172.      {
  173.       edges[c][0]--; edges[c][1]--;
  174.      }
  175.  
  176.      initialise_graphics();
  177.  
  178.      translate(0,0,0,w2v);
  179.      transform(w2v);
  180.      draw_picture();
  181.      do
  182.      {
  183.        ch=getch();
  184.        switch (ch)
  185.        {
  186.        case '8': {
  187.                translate(0,0,-10,temp);
  188.                mult_4x4(w2v,temp,temp2);
  189.                copy_4x4(temp2,w2v);
  190.                break;
  191.              };
  192.        case    '2': {
  193.                translate(0,0,10,temp);
  194.                mult_4x4(w2v,temp,temp2);
  195.                copy_4x4(temp2,w2v);
  196.                break;
  197.              };
  198.        case    '4': {
  199.                translate(10,0,0,temp);
  200.                mult_4x4(w2v,temp,temp2);
  201.                copy_4x4(temp2,w2v);
  202.                break;
  203.              };
  204.        case    '6': {
  205.                translate(-10,0,0,temp);
  206.                mult_4x4(w2v,temp,temp2);
  207.                copy_4x4(temp2,w2v);
  208.                break;
  209.              };
  210.        case    '1': {
  211.                translate(0,10,0,temp);
  212.                mult_4x4(w2v,temp,temp2);
  213.                copy_4x4(temp2,w2v);
  214.                break;
  215.              };
  216.        case    '7': {
  217.                translate(0,-10,0,temp);
  218.                mult_4x4(w2v,temp,temp2);
  219.                copy_4x4(temp2,w2v);
  220.                break;
  221.              };
  222.        case    ',': {
  223.                rotate_y(PI/180.0,temp);
  224.                mult_4x4(w2v,temp,temp2);
  225.                copy_4x4(temp2,w2v);
  226.                break;
  227.              };
  228.        case    '.': {
  229.                rotate_y(-PI/180.0,temp);
  230.                mult_4x4(w2v,temp,temp2);
  231.                copy_4x4(temp2,w2v);
  232.                break;
  233.              };
  234.        case    'm': {
  235.                rotate_z(PI/180.0,temp);
  236.                mult_4x4(w2v,temp,temp2);
  237.                copy_4x4(temp2,w2v);
  238.                break;
  239.              };
  240.        case    'n': {
  241.                rotate_z(-PI/180.0,temp);
  242.                mult_4x4(w2v,temp,temp2);
  243.                copy_4x4(temp2,w2v);
  244.                break;
  245.              };
  246.        case    'o': {
  247.                rotate_x(PI/180.0,temp);
  248.                mult_4x4(w2v,temp,temp2);
  249.                copy_4x4(temp2,w2v);
  250.                break;
  251.              };
  252.        case    'l': {
  253.                rotate_x(-PI/180.0,temp);
  254.                mult_4x4(w2v,temp,temp2);
  255.                copy_4x4(temp2,w2v);
  256.                break;
  257.              };
  258.        };
  259.        transform(w2v);
  260.        draw_picture();
  261.      }
  262.      while (ch!='q');
  263.      closegraph();
  264. }