home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / spline-patch.tar.gz / spline-patch.tar / patch / demos / demo2.c < prev    next >
C/C++ Source or Header  |  1991-11-18  |  10KB  |  366 lines

  1. /*
  2.  *   demo2.c:
  3.  *
  4.  *     draws three surface patches:  RED   == Bezier
  5.  *                                   BLUE  == B-Spline
  6.  *                                   GREEN == Cardinal
  7.  *
  8.  * Copyright (c) 1990, by Sean Graves and Texas A&M University
  9.  *
  10.  * Permission is hereby granted for non-commercial reproduction and use of
  11.  * this program, provided that this notice is included in any material copied
  12.  * from it. The author assumes no responsibility for damages resulting from
  13.  * the use of this software, however caused.
  14.  *
  15.  */
  16.  
  17. #include "gl.h"
  18. #include "device.h"
  19. #include "math.h"
  20. #include "stdio.h"
  21. #include "patch.h"                  /* My stuff */
  22.  
  23. MATRIX beziermatrix = { { -1,  3, -3, 1 },
  24.                         {  3, -6,  3, 0 },
  25.                         { -3,  3,  0, 0 },
  26.                         {  1,  0,  0, 0 } };        
  27.  
  28. MATRIX cardinalmatrix = { { -0.5,  1.5, -1.5,  0.5 },
  29.                           {  1.0, -2.5,  2.0, -0.5 },
  30.                           { -0.5,  0.0,  0.5,  0.0 },
  31.                           {  0.0,  1.0,  0.0,  0.0 } };        
  32.  
  33. MATRIX bsplinematrix = { { -1.0/6.0,  3.0/6.0, -3.0/6.0, 1.0/6.0 },
  34.                          {  3.0/6.0, -6.0/6.0,  3.0/6.0,     0.0 },
  35.                          { -3.0/6.0,      0.0,  3.0/6.0,     0.0 },
  36.                          {  1.0/6.0,  4.0/6.0,  1.0/6.0,     0.0 } };        
  37.  
  38. #define BEZIER 1
  39. #define CARDINAL 2
  40. #define BSPLINE 3
  41.  
  42. #define DIV 8
  43.  
  44. MATRIX geomx = { {   0.0,   0.0,   0.0,   0.0},
  45.                  {   0.0, 100.0, 100.0,   0.0},
  46.                  { 300.0, 200.0, 200.0, 300.0},
  47.                  { 300.0, 300.0, 300.0, 300.0} };        
  48.  
  49. MATRIX geomy = { { 200.0,   0.0, 200.0, 200.0},
  50.                  {   0.0,   0.0, 200.0,   0.0},
  51.                  {   0.0,   0.0, 200.0,   0.0},
  52.                  { 200.0,   0.0, 200.0, 200.0} };        
  53.  
  54. MATRIX geomz = { { 100.0, 200.0, 300.0, 400.0 },
  55.                  { 100.0, 200.0, 300.0, 400.0 },
  56.                  { 100.0, 200.0, 300.0, 400.0 },
  57.                  { 100.0, 200.0, 300.0, 400.0 } };        
  58.  
  59.  
  60. PatchPtr mypatch[3];
  61. ListPtr insert_node();
  62.  
  63. /*******************************************************************/
  64.  
  65. main()
  66. {
  67.     Device dev;
  68.     short val;
  69.  
  70.     initialize();
  71.  
  72.     while (TRUE) {
  73.  
  74.         if (qtest()) {
  75.        
  76.             dev = qread(&val);
  77.  
  78.             if (dev == ESCKEY) {
  79.                 gexit();
  80.                 exit();
  81.             } else if (dev == REDRAW) {
  82.                 reshapeviewport();
  83.                 drawpatches();
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. /*******************************************************************/
  90.  
  91. initialize()
  92. {
  93.     int gid;
  94.  
  95.     
  96. prefposition(XMAXSCREEN/4,XMAXSCREEN*3/4,YMAXSCREEN/4,YMAXSCREEN*3/4);
  97.     gid = winopen("testpatch");
  98.     winset(gid);
  99.     winattach();
  100.     winconstraints();
  101.  
  102.     qdevice(ESCKEY);
  103.     qdevice(REDRAW);
  104.     qenter(REDRAW,gid);
  105.     perspective(900, 1.0, 1.0, 10000.0 );
  106.     lookat(400.0, 400.0, 0.0, 200.0, 200.0, 250.0,0); 
  107.     mypatch[0] = NewPatch();
  108.     DefPatch(mypatch[0], beziermatrix, geomx, geomy, geomz, DIV);
  109.     mypatch[1] = NewPatch();
  110.     DefPatch(mypatch[1], cardinalmatrix, geomx, geomy, geomz, DIV);
  111.     mypatch[2] = NewPatch();
  112.     DefPatch(mypatch[2], bsplinematrix, geomx, geomy, geomz, DIV);
  113.     srand48(123);
  114. }
  115.  
  116. /*******************************************************************/
  117.  
  118. drawpatches()
  119. {
  120.    TreePtr tree;
  121.    int i,j;
  122.    float vert[3], mag;
  123.    RAY r;
  124.  
  125.    while (1) { 
  126.       color(BLACK);
  127.       clear();
  128.       drawaxes();
  129.       color(RED);
  130.       drawpatch(mypatch[0]);
  131.  
  132.       r.org.x = 150.0;
  133.       r.org.y = 400.0;
  134.       r.org.z = 200.0;
  135.  
  136.       r.dir.x = (float) drand48() / 2.0;
  137.       r.dir.y = (float) drand48();
  138.       r.dir.z = (float) drand48() / 2.0;
  139.  
  140.       mag = sqrt(r.dir.x*r.dir.x+r.dir.y*r.dir.y+r.dir.z*r.dir.z);
  141.  
  142.       r.dir.x = r.dir.x / mag;
  143.       r.dir.y = - fabs(r.dir.y / mag);
  144.       r.dir.z = r.dir.z / mag;
  145.  
  146.       color(WHITE);
  147.       bgnline();
  148.          vert[0] = r.org.x ;
  149.          vert[1] = r.org.y ;
  150.          vert[2] = r.org.z ;
  151.          v3f(vert);
  152.          vert[0] = r.org.x + 400 * r.dir.x;
  153.          vert[1] = r.org.y + 400 * r.dir.y;
  154.          vert[2] = r.org.z + 400 * r.dir.z;
  155.          v3f(vert);
  156.       endline();
  157.       color(GREEN);
  158.       testbox(mypatch[0]->tree, r);
  159.       sleep(1);
  160.   }
  161. /*
  162.    color(WHITE);
  163.    drawhull(mypatch[0]);
  164. */
  165. }
  166.  
  167. /***************************************************************************/
  168.  
  169. drawaxes()
  170. {
  171.    float vert[3];
  172.  
  173.    color(RED);
  174.    bgnline(); vert[0]=0 ; vert[1]=0; vert[2]=0; v3f(vert);
  175.               vert[0]=20; vert[1]=0; vert[2]=0; v3f(vert); endline();
  176.    color(GREEN);
  177.    bgnline(); vert[0]=0; vert[1]=0 ; vert[2]=0; v3f(vert);
  178.               vert[0]=0; vert[1]=20; vert[2]=0; v3f(vert); endline();
  179.    color(BLUE);
  180.    bgnline(); vert[0]=0; vert[1]=0; vert[2]=0 ; v3f(vert);
  181.               vert[0]=0; vert[1]=0; vert[2]=20; v3f(vert); endline();
  182. }
  183.  
  184. /***************************************************************************/
  185.  
  186. drawhull(p)
  187. PatchPtr p;
  188. {
  189.    int i, j;
  190.    float vert[3];
  191.    
  192.    for (i = 0; i < 4; i++) {
  193.         bgnline();
  194.     for (j = 0; j <4; j++) {
  195.       vert[0] = p->geomx[j][i];
  196.       vert[1] = p->geomy[j][i];
  197.       vert[2] = p->geomz[j][i];
  198.       v3f(vert);
  199.     }
  200.     endline();
  201.    }    
  202.    for (i = 0; i < 4; i++) {
  203.         bgnline();
  204.     for (j = 0; j <4; j++) {
  205.       vert[0] = p->geomx[i][j];
  206.       vert[1] = p->geomy[i][j];
  207.       vert[2] = p->geomz[i][j];
  208.       v3f(vert);
  209.     }
  210.     endline();
  211.    }
  212. }
  213.  
  214. /**********************************************************************/
  215.  
  216. drawpatch(p)
  217. PatchPtr p;
  218. {
  219.    float U[1][4], V[4][1];              /* u, v vectors */
  220.    float C[4][4];                       /* solution matrix (only [0][0] used) */
  221.    float M2x[4][4], M2y[4][4], M2z[4][4]; /* Intermediate results */
  222.    float u, v;                     /* Parameters */
  223.    float M2xdu[4][4], M2xdv[4][4]; /* Intermed. results for surface normals */
  224.    float M2ydu[4][4], M2ydv[4][4];
  225.    float M2zdu[4][4], M2zdv[4][4];
  226.    VECTOR ddu, ddv, norm;
  227.  
  228.    float vert[3], vert2[3];                  /* Screen vertices */
  229.  
  230.    for (v = 0; v <= 1.0; v += 0.2) {
  231.       V[3][0] = 1;
  232.       V[2][0] = v;
  233.       V[1][0] = v * v;
  234.       V[0][0] = V[1][0] * v;
  235.       mmult4x4_4x1 (M2x, p->Mx, V);  /* Calculate intermediate results with v */
  236.       mmult4x4_4x1 (M2y, p->My, V);
  237.       mmult4x4_4x1 (M2z, p->Mz, V);
  238.  
  239.       mmult4x4_4x1 (M2xdu, p->Mxdu, V);
  240.       mmult4x4_4x1 (M2ydu, p->Mydu, V);
  241.       mmult4x4_4x1 (M2zdu, p->Mzdu, V);
  242.       
  243.       mmult4x4_4x1 (M2xdv, p->Mxdv, V);
  244.       mmult4x4_4x1 (M2ydv, p->Mydv, V);
  245.       mmult4x4_4x1 (M2zdv, p->Mzdv, V);
  246.       bgnline();
  247.       for (u = 0; u <= 1.0; u += 0.02) {
  248.         U[0][3] = 1;
  249.         U[0][2] = u;
  250.         U[0][1] = u * u;
  251.         U[0][0] = U[0][1] * u;
  252.         mmult1x4_4x1 (C, U, M2x);
  253.         vert[0] = C[0][0];
  254.         mmult1x4_4x1 (C, U, M2y);
  255.         vert[1] = C[0][0];
  256.         mmult1x4_4x1 (C, U, M2z);
  257.         vert[2] = C[0][0];
  258.         v3f(vert);     
  259.         if (fcmp(u,0.0) || fcmp(u, 0.2) || fcmp(u,0.4) || fcmp(u, 0.6) || 
  260.            fcmp(u, 0.8) || fcmp(u,1.0)) {
  261.            mmult1x4_4x1 (C, U, M2xdu);
  262.            ddu.x = C[0][0];
  263.            mmult1x4_4x1 (C, U, M2ydu);
  264.            ddu.y = C[0][0];
  265.            mmult1x4_4x1 (C, U, M2zdu);
  266.            ddu.z = C[0][0];
  267.            mmult1x4_4x1 (C, V, M2xdv);
  268.            ddv.x = C[0][0];
  269.            mmult1x4_4x1 (C, V, M2ydv);
  270.            ddv.y = C[0][0];
  271.            mmult1x4_4x1 (C, V, M2zdv);
  272.            ddv.z = C[0][0];
  273.            cross_product(&norm, ddu, ddv);
  274.            normalize(&norm); 
  275.            vert2[0] = vert[0] + 20.0 * norm.x;
  276.            vert2[1] = vert[1] + 20.0 * norm.y;
  277.            vert2[2] = vert[2] + 20.0 * norm.z;
  278.            v3f(vert2);
  279.            v3f(vert);      
  280.         } 
  281.       }
  282.       endline();
  283.    }
  284.  
  285.    for (u = 0; u <= 1.0; u += 0.2) {
  286.       U[0][3] = 1;
  287.       U[0][2] = u;
  288.       U[0][1] = u * u;
  289.       U[0][0] = U[0][1] * u;
  290.       mmult1x4_4x4 (M2x, U, p->Mx);
  291.       mmult1x4_4x4 (M2y, U, p->My);
  292.       mmult1x4_4x4 (M2z, U, p->Mz);
  293.       bgnline();
  294.       for (v = 0; v <= 1.0; v += 0.02) {
  295.         V[3][0] = 1;
  296.         V[2][0] = v;
  297.         V[1][0] = v * v;
  298.         V[0][0] = V[1][0] * v;
  299.         mmult1x4_4x1 (C, M2x, V);
  300.         vert[0] = C[0][0];
  301.         mmult1x4_4x1 (C, M2y, V);
  302.         vert[1] = C[0][0];
  303.         mmult1x4_4x1 (C, M2z, V);
  304.         vert[2] = C[0][0];
  305.         v3f(vert);      
  306.       }
  307.       endline();
  308.    }
  309. }
  310.  
  311. /*********************************************************************** ****/
  312.  
  313. drawbox(min, max)
  314. POINT min, max;
  315. {
  316.    float vert[8][3];
  317.  
  318.    bgnline();
  319.    vert[0][0] = min.x; vert[0][1] = min.y; vert[0][2] = min.z;
  320.    vert[1][0] = max.x; vert[1][1] = min.y; vert[1][2] = min.z;
  321.    vert[2][0] = max.x; vert[2][1] = max.y; vert[2][2] = min.z;
  322.    vert[3][0] = min.x; vert[3][1] = max.y; vert[3][2] = min.z;
  323.    vert[4][0] = min.x; vert[4][1] = min.y; vert[4][2] = max.z;
  324.    vert[5][0] = max.x; vert[5][1] = min.y; vert[5][2] = max.z;
  325.    vert[6][0] = max.x; vert[6][1] = max.y; vert[6][2] = max.z;
  326.    vert[7][0] = min.x; vert[7][1] = max.y; vert[7][2] = max.z;
  327.  
  328.    v3f(vert[0]);
  329.    v3f(vert[1]);
  330.    v3f(vert[2]);
  331.    v3f(vert[3]);
  332.    v3f(vert[0]);
  333.    v3f(vert[3]);
  334.    v3f(vert[7]);
  335.    v3f(vert[4]);
  336.    v3f(vert[0]);
  337.    v3f(vert[4]);
  338.    v3f(vert[5]);
  339.    v3f(vert[6]);
  340.    v3f(vert[7]);
  341.    v3f(vert[6]);
  342.    v3f(vert[2]);
  343.    v3f(vert[1]);
  344.    v3f(vert[5]);
  345.    endline();
  346. }
  347.    
  348. /*****************************************************************/
  349.  
  350. testbox(tree, r)
  351. TreePtr tree;
  352. RAY r;
  353. {
  354.    int i;
  355.    Isectrec irec;
  356.  
  357.    if (BoxIntersect(r,tree->box_min,tree->box_max) != -1.0) {
  358.       drawbox(tree->box_min, tree->box_max); 
  359.       if (tree->child[0]) {
  360.          for (i = 0; i < 4; i++)
  361.             testbox(tree->child[i], r);
  362.       } else 
  363.          irec = IsectPatch(mypatch[0], r);
  364.    }
  365. }
  366.