home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / 3Dmodeling / trackball.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.0 KB  |  322 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* Tom Davis -- 1992 */
  19.  
  20. #include <stdio.h>
  21. #include <math.h>
  22. #include <gl.h>
  23. #include <device.h>
  24.  
  25. /* This is a trackball interface for manipulation of a 3D model.  To
  26.  * use it, you must provide a routine that draws the 3D model you want
  27.  * to manipulate, where your routine does any clear() and zclear()
  28.  * commands that are necessary.  Before starting, you should also set
  29.  * up the correct perspective or ortho projection command.  For now,
  30.  * we assume that you are running in RGB mode and in MVIEWING mode.
  31.  *
  32.  * Then call trackmodel passing your drawing routine as the first
  33.  * parameter, followed by 4 floating point numbers.  The first is the
  34.  * distance of the eye from the center of rotation, and the last 3
  35.  * are the x, y, and z coordinates of the center of rotation.
  36.  *
  37.  * The interface uses the left mouse button to control the motion of
  38.  * the virtual trackball in which your model is embedded, and pressing
  39.  * the "Q" key on the keyboard or the right mouse button returns
  40.  * from the routine.
  41.  *
  42.  * At the end of this file is a completely commented-out copy of a
  43.  * sample program that uses the trackmodel() routine.  To try it, simply
  44.  * add the line:
  45.  *
  46.  * #define TESTPROG
  47.  *
  48.  * immediately following this comment.
  49.  *
  50.  *  -- Tom Davis    March, 1991
  51.  */
  52.  
  53. static float idmat[4][4] = {
  54.     { 1.0, 0.0, 0.0, 0.0},
  55.     { 0.0, 1.0, 0.0, 0.0},
  56.     { 0.0, 0.0, 1.0, 0.0},
  57.     { 0.0, 0.0, 0.0, 1.0}
  58. };
  59.  
  60. float tmat[4][4];
  61.  
  62. static long    xorg, xsize, yorg, ysize;
  63.  
  64. static trackdraw(drawroutine, d, cx, cy, cz)
  65. void (*drawroutine)();
  66. float d, cx, cy, cz;
  67. {
  68.     float M[4][4];
  69.  
  70.     loadmatrix(idmat);
  71.     pushmatrix();
  72.     lookat(0.0, 0.0, d, 0.0, 0.0, 0.0, 0);
  73.     multmatrix(tmat);
  74.     translate(-cx, -cy, -cz);
  75.     (*drawroutine)();
  76.     popmatrix();
  77.     mmode(MPROJECTION);
  78.     getmatrix(M);
  79.     mmode(MVIEWING);
  80.     ortho2(-1.0, 1.0, -1.0, 1.0);
  81.     cpack(0x00ff00);
  82.     circ(0.0, 0.0, 0.75);
  83.     mmode(MPROJECTION);
  84.     loadmatrix(M);
  85.     mmode(MVIEWING);
  86.     swapbuffers();
  87. }
  88.  
  89. static trackcursor(mat, drawroutine, d, cx, cy, cz)
  90. float mat[4][4];
  91. void (*drawroutine)();
  92. float d, cx, cy, cz;
  93. {
  94.     static float zdown[3], sx, sy;
  95.     float zcur[3], t1[3], t2[3], t3[3], m[3][3], mtemp[3][3];
  96.     int i, j;
  97.     float px, py, dpx, dpy, rad, dx, dy, dz, u;
  98.     float M[4][4];
  99.  
  100.     loadmatrix(idmat);
  101.  
  102.     getorigin(&xorg, &yorg);
  103.     getsize(&xsize, &ysize);
  104.     for (i=0; i<3; i++) {
  105.     mtemp[i][0] = mat[i][0];
  106.     mtemp[i][1] = mat[i][1];
  107.     mtemp[i][2] = mat[i][2];
  108.     }
  109.     sx = xsize;
  110.     sy = ysize;
  111.     rad = sy*3.0/8.0;
  112.     dpx = getvaluator(MOUSEX);
  113.     dpy = getvaluator(MOUSEY);
  114.     dx = dpx - sx/2 - xorg;
  115.     dy = dpy - sy/2 - yorg;
  116.     if ((u = rad*rad - dx*dx - dy*dy) < 0.0)
  117.     dz = 0;
  118.     else
  119.     dz = sqrt(u);
  120.     zdown[0] = dx; zdown[1] = dy; zdown[2] = dz;
  121.     normalize(zdown);
  122.  
  123.     while (!qtest()) {
  124.     px = getvaluator(MOUSEX);
  125.     py = getvaluator(MOUSEY);
  126.     if (px == dpx && py == dpy)
  127.         continue;
  128.     dx = px - sx/2 - xorg;
  129.     dy = py - sy/2 - yorg;
  130.     if ((u = rad*rad - dx*dx - dy*dy) < 0.0)
  131.         dz = 0;
  132.     else
  133.         dz = sqrt(u);
  134.     zcur[0] = dx; zcur[1] = dy; zcur[2] = dz;
  135.     normalize(zcur);
  136.     crossprod(zdown, zcur, t1);
  137.     normalize(t1);
  138.     crossprod(zdown, t1, t2);
  139.     crossprod(zcur, t1, t3);
  140.     normalize(t2);
  141.     normalize(t3);
  142.     for (i = 0; i < 3; i++)
  143.         for (j = 0; j < 3; j++)
  144.         m[j][i] = zdown[i]*zcur[j]+t1[i]*t1[j]+t2[i]*t3[j];
  145.  
  146.     for (i = 0; i < 3; i++)
  147.         for (j = 0; j < 3; j++)
  148.         mat[j][i] =
  149.             m[i][0]*mtemp[j][0]+m[i][1]*mtemp[j][1]+m[i][2]*mtemp[j][2];
  150.     pushmatrix();
  151.     lookat(0.0, 0.0, d, 0.0, 0.0, 0.0, 0);
  152.     multmatrix(mat);
  153.     translate(-cx, -cy, -cz);
  154.     (*drawroutine)();
  155.     popmatrix();
  156.     mmode(MPROJECTION);
  157.     getmatrix(M);
  158.     mmode(MVIEWING);
  159.     ortho2(-1.0, 1.0, -1.0, 1.0);
  160.     cpack(0x00ff00);
  161.     circ(0.0, 0.0, 0.75);
  162.     mmode(MPROJECTION);
  163.     loadmatrix(M);
  164.     mmode(MVIEWING);
  165.     swapbuffers();
  166.     }
  167. }
  168.  
  169. static identifymat4(m)
  170. float m[4][4];
  171. {
  172.     bcopy(idmat, m, 16*sizeof(float));
  173. }
  174.  
  175. trackmodel(drawroutine, d, cx, cy, cz)
  176. void (*drawroutine)();
  177. float d, cx, cy, cz;
  178. {
  179.     short dev, val;
  180.  
  181.     qdevice(LEFTMOUSE);
  182.     qdevice(RIGHTMOUSE);
  183.     qdevice(QKEY);
  184.     identifymat4(tmat);
  185.  
  186.     trackdraw(drawroutine, d, cx, cy, cz);
  187.     while (1) {
  188.     if (qtest()) {
  189.         switch(dev = qread(&val)) {
  190.         case LEFTMOUSE:
  191.             if (val == 0) break;
  192.             trackcursor(tmat, drawroutine, d, cx, cy, cz);
  193.         case QKEY:
  194.             if (val == 0) return;
  195.             break;
  196.         case RIGHTMOUSE:
  197.             if (val == 1) return;
  198.             break;
  199.         case REDRAW:
  200.             reshapeviewport();
  201.             trackdraw(drawroutine, d, cx, cy, cz);
  202.             break;            
  203.         default:
  204.             break;
  205.         }
  206.     }
  207.     }
  208. }
  209.  
  210.  
  211. /*************************  END OF LIBRARY ROUTINES ****************************/
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221. #ifdef TESTPROG
  222.  
  223. #define ANGLE    400
  224.  
  225. float white_light[] = {
  226.     LCOLOR, 0.8, 0.8, 0.8,
  227.     AMBIENT, 0.7, 0.1, 0.1,
  228.     POSITION, -0.2, 0.2, 0.2, 0., 
  229.     LMNULL,
  230. };
  231.  
  232. float  purple_material[] = {SPECULAR, 0.3, 0.3, 0.3,
  233.                 DIFFUSE,  0.8, 0.0, 0.8,
  234.                 SHININESS,5.0,
  235.                 AMBIENT,  0.7, 0.0, 0.2, 
  236.                 LMNULL};
  237.  
  238. float n[3] = {0.0, 0.0, 1.0};
  239.  
  240. float v[4][3] = {{-2.0, -2.0, 0.0}, {-2.0, 2.0, 0.0},
  241.          {2.0, 2.0, 0.0}, {2.0, -2.0, 0.0}};
  242.  
  243. void drawobject()
  244. {
  245.     zclear();
  246.     cpack(0xffffff);
  247.     clear();
  248.     pushmatrix();
  249.     n3f(n);
  250.     bgnpolygon();
  251.     v3f(&v[0][0]);
  252.     v3f(&v[1][0]);
  253.     v3f(&v[2][0]);
  254.     v3f(&v[3][0]);
  255.     endpolygon();
  256.     rotate(900, 'x');
  257.     n3f(n);
  258.     bgnpolygon();
  259.     v3f(&v[0][0]);
  260.     v3f(&v[1][0]);
  261.     v3f(&v[2][0]);
  262.     v3f(&v[3][0]);
  263.     endpolygon();
  264.     rotate(900, 'y');
  265.     n3f(n);
  266.     bgnpolygon();
  267.     v3f(&v[0][0]);
  268.     v3f(&v[1][0]);
  269.     v3f(&v[2][0]);
  270.     v3f(&v[3][0]);
  271.     endpolygon();
  272.     popmatrix();
  273.     translate(4.0, 0.0, 0.0);
  274.     n3f(n);
  275.     bgnpolygon();
  276.     v3f(&v[0][0]);
  277.     v3f(&v[1][0]);
  278.     v3f(&v[2][0]);
  279.     v3f(&v[3][0]);
  280.     endpolygon();
  281.     rotate(900, 'x');
  282.     n3f(n);
  283.     bgnpolygon();
  284.     v3f(&v[0][0]);
  285.     v3f(&v[1][0]);
  286.     v3f(&v[2][0]);
  287.     v3f(&v[3][0]);
  288.     endpolygon();
  289.     rotate(900, 'y');
  290.     n3f(n);
  291.     bgnpolygon();
  292.     v3f(&v[0][0]);
  293.     v3f(&v[1][0]);
  294.     v3f(&v[2][0]);
  295.     v3f(&v[3][0]);
  296.     endpolygon();
  297. }
  298.  
  299. main()
  300. {
  301.     short val;
  302.  
  303.     keepaspect(1, 1);
  304.     winopen("track");
  305.     qdevice(LEFTMOUSE);
  306.     doublebuffer();
  307.     RGBmode();
  308.     gconfig();
  309.     zbuffer(1);
  310.     lmdef(DEFMATERIAL,1,15,purple_material);
  311.     lmdef(DEFLIGHT,2,14,white_light);
  312.     lmdef(DEFLMODEL,1,0,0);
  313.     mmode(MVIEWING);
  314.     perspective(ANGLE, 1.0, 1.0, 50.0);
  315.     lmbind(MATERIAL,1);
  316.     lmbind(LIGHT1,2);
  317.     lmbind(LMODEL,1);
  318.     trackmodel(drawobject, 25.0, 2.0, 0.0, 0.0);
  319. }
  320.  
  321. #endif /* TESTPROG */
  322.