home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / IRITS.ZIP / XVIEWOBJ.C < prev   
Encoding:
C/C++ Source or Header  |  1990-05-05  |  10.5 KB  |  296 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber            Unix - X11 Ver 0.1, Mar. 1990    *
  5. ******************************************************************************
  6. * Module to handle viewing of objects in the ViewWindow.             *
  7. *****************************************************************************/
  8.  
  9. #ifndef __MSDOS__
  10.  
  11. #include <stdio.h>
  12. #include <math.h>
  13. #include "program.h"
  14. #include "windowsl.h"
  15. #include "windowsg.h"
  16. #include "viewobjl.h"
  17. #include "viewobjg.h"
  18. #include "graphgng.h"
  19. #include "objects.h"
  20.  
  21. #include "xgraphic.h"
  22.  
  23. static int ViewNormals = FALSE, NormalsColor = 1, /* View normals to object. */
  24.        QuitView = FALSE;
  25. static RealType NormalsSize = 0.1;
  26. static ObjectStruct *ActiveObjList = NULL;   /* Currently displayed objects. */
  27.  
  28. /*****************************************************************************
  29. *  Routine to interactively display geometric object(s) PObjList on the View *
  30. * window enable rotating/translating/scaling it using the Input Device.      *
  31. *****************************************************************************/
  32. void InteractGeomObject(ObjectStruct *PObjList, RealType *UpdateGlblMat)
  33. {
  34.     struct ObjectStruct *ViewMat;
  35.     MatrixType ViewMatCopy;     /* Save original transformation to recover. */
  36.  
  37.     if (!IS_OLST_OBJ(PObjList))
  38.     FatalError("InteractGeomObject: Not object list object!\n");
  39.  
  40.     if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
  41.     WndwInputWindowPutStr(
  42.         "No view transformation matrix VIEW_MAT!", RED);
  43.     return;
  44.     }
  45.     else if (!IS_MAT_OBJ(ViewMat)) {
  46.     WndwInputWindowPutStr(
  47.         "VIEW_MAT object was modified (not matrix object)", RED);
  48.     return;
  49.     }
  50.     MAT_COPY(ViewMatCopy, ViewMat -> U.Mat);
  51.  
  52.     /* Get data from input device, interpret it, and display interactively:  */
  53.     InteractHandleInput(PObjList, ViewMat -> U.Mat);
  54.  
  55.     if (!APX_EQ(*UpdateGlblMat, 0.0))
  56.     MAT_COPY(ViewMat -> U.Mat, ViewMatCopy);         /* Recover. */
  57. }
  58.  
  59. /*****************************************************************************
  60. *  Routine to handle data from the input device (keyboard, mouse etc.) -     *
  61. * clip it against the sub windows of the interactive menu and perform the    *
  62. * required transfomation, by updating the global view matrix object VIEW_MAT *
  63. *  The input data in the Rotation/Translation/Scaling sub windows is used    *
  64. * (horizontal distance from sub window center) to set amount of change.         *
  65. *****************************************************************************/
  66. static void InteractHandleInput(ObjectStruct *PObjList, MatrixType GlblViewMat)
  67. {
  68.     int i, UpdateView, ScreenCoord = TRUE;
  69.     char *ToggleStr;
  70.     RealType x, y, ChangeFactor;
  71.     MatrixType Mat;
  72.  
  73.     ActiveObjList = PObjList;
  74.  
  75.     QuitView = FALSE;
  76.     UpdateInteractHandleInput();       /* Display it for the first time. */
  77.  
  78.     while (TRUE) {
  79.     QuitView = FALSE;
  80.  
  81.     UpdateView = TRUE;
  82.  
  83.     switch (GetGraphicEvent(&ChangeFactor, &ToggleStr)) {
  84.         case EVENT_SCR_OBJ_TGL:    /* Its Coordinate system - toggle it. */
  85.         ScreenCoord = *ToggleStr == 'S';
  86.         UpdateView = FALSE;
  87.         break;
  88.         case EVENT_ROTATE_X:       /* Its rotation along the X axis. */
  89.         MatGenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  90.         break;
  91.         case EVENT_ROTATE_Y:       /* Its rotation along the Y axis. */
  92.         MatGenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  93.         break;
  94.         case EVENT_ROTATE_Z:       /* Its rotation along the Z axis. */
  95.         MatGenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  96.         break;
  97.         case EVENT_TRANSLATE_X:    /* Its translation along the X axis. */
  98.         MatGenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0,
  99.                                     Mat);
  100.         break;
  101.         case EVENT_TRANSLATE_Y:    /* Its translation along the Y axis. */
  102.         MatGenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0,
  103.                                     Mat);
  104.         break;
  105.         case EVENT_TRANSLATE_Z:    /* Its translation along the Z axis. */
  106.         MatGenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR,
  107.                                     Mat);
  108.         break;
  109.         case EVENT_SCALE:              /* Its scaling along all axes. */
  110.         if (ChangeFactor > 0.0)              /* Make it around 1... */
  111.              ChangeFactor = ChangeFactor * MAX_SCALE_FACTOR + 1.0;
  112.         else ChangeFactor = 1.0 /
  113.             (-ChangeFactor * MAX_SCALE_FACTOR + 1.0);
  114.         MatGenMatScale(ChangeFactor, ChangeFactor, ChangeFactor, Mat);
  115.         break;
  116.         case EVENT_QUIT:
  117.         ActiveObjList = NULL;
  118.         return;                        /* Its Quit. */
  119.         default:
  120.         FatalError("InteractHandleInput: Undefine input type, exit\n");
  121.     }
  122.     if (UpdateView) {
  123.         if (ScreenCoord)        /* Udpate the global viewing matrix. */
  124.          MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
  125.         else MatMultTwo4by4(GlblViewMat, Mat, GlblViewMat);
  126.         UpdateInteractHandleInput();
  127.     }
  128.     }
  129. }
  130.  
  131. /*****************************************************************************
  132. *  Routine to update the viewing screen. On unix systems this routine may    *
  133. * be invoked when X sends expose event to this program (see xgrphgen.c).     *
  134. * In MSDOS this routine is static and been called from InteractHandleInput   *
  135. * above routine only.                                 *
  136. *****************************************************************************/
  137. void UpdateInteractHandleInput(void)
  138. {
  139.     GGClearAllScreen();
  140.     if (ActiveObjList != NULL)
  141.     ViewGeomObjectList(ActiveObjList);        /* And display it... */
  142. }
  143.  
  144. /*****************************************************************************
  145. *  Routine to display the geometric objects in PObjList, by simply calling   *
  146. * ViewGeomObject on all of them. PObjList must be of type OBJ_LIST_OBJ.         *
  147. *****************************************************************************/
  148. static void ViewGeomObjectList(ObjectStruct *PObjList)
  149. {
  150.     int Param = 0;
  151.     struct ObjectStruct *PObj;
  152.     char Line[LINE_LEN];
  153.  
  154.     while ((PObj = PObjList -> U.PObjList[Param]) != NULL &&
  155.        Param++ < MAX_OBJ_LIST && !QuitView) {
  156.     if (!IS_GEOM_OBJ(PObj)) {
  157.         sprintf(Line, "Cannt display none geometric object %s, ignored",
  158.         PObj -> Name);
  159.         WndwInputWindowPutStr(Line, RED);
  160.         continue;
  161.     }
  162.     ViewGeomObject(PObj);
  163.     }
  164. }
  165.  
  166. /*****************************************************************************
  167. *  Routine to fetch the internal parameter from the INTERNAL object.         *
  168. *****************************************************************************/
  169. static int GetInternal(void)
  170. {
  171.     int Internal;
  172.     struct ObjectStruct *PObj = GetObject("INTERNAL");
  173.  
  174.     if (PObj == NULL || !IS_NUM_OBJ(PObj)) {
  175.     WndwInputWindowPutStr("No numeric object name INTERNAL is defined",
  176.                                     RED);
  177.     Internal = DEFAULT_INTERNAL;
  178.     }
  179.     else Internal = !APX_EQ((PObj -> U.R), 0.0);
  180.  
  181.     return Internal;
  182. }
  183.  
  184. /*****************************************************************************
  185. *  Routine to display the geometric object PObj on the View Window:         *
  186. * Uses the global view transformation matrix ViewMat as view point.         *
  187. *****************************************************************************/
  188. void ViewGeomObject(ObjectStruct *PObj)
  189. {
  190.     int Color, ShowNormals, ViewInternal = GetInternal();
  191.     struct PolygonStruct *Pl;
  192.     struct ObjectStruct *ViewMat;
  193.  
  194.     QuitView = FALSE;
  195.  
  196.     if (!IS_GEOM_OBJ(PObj))
  197.     FatalError("ViewGeomObject: Not geometric object!\n");
  198.  
  199.     Pl = PObj -> U.Pl;
  200.  
  201.     if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
  202.     WndwInputWindowPutStr(
  203.         "No view transformation matrix VIEW_MAT!", RED);
  204.     return;
  205.     }
  206.     else if (!IS_MAT_OBJ(ViewMat)) {
  207.     WndwInputWindowPutStr(
  208.         "VIEW_MAT object was modified (not matrix object)\n", RED);
  209.     return;
  210.     }
  211.  
  212.     Color = GET_OBJECT_COLOR(PObj);
  213.     ShowNormals = (ViewNormals && !IS_POLYLINE_GEOM_OBJ(PObj));
  214.  
  215.     while (Pl && !QuitView) {
  216.     ViewPolygon(Pl, Color, ShowNormals, ViewMat -> U.Mat, ViewInternal);
  217.     Pl = Pl -> Pnext;
  218.     TestQuitView();       /* if break display in the middle - Set QuitView. */
  219.     }
  220.  
  221.     GraphicFlush();
  222. }
  223.  
  224. /*****************************************************************************
  225. *  Routine to test if quit display event - occured -                 *
  226. * Right button was clicked on mouse.                         *
  227. *****************************************************************************/
  228. static void TestQuitView(void)
  229. {
  230.     QuitView = IsAbortKeyPressed();
  231. }
  232.  
  233. /*****************************************************************************
  234. *  Routine to display one polygon on the view window using the matrix Mat as *
  235. * a transformation matrix.                             *
  236. *****************************************************************************/
  237. static void ViewPolygon(PolygonStruct *Pl, int Color, int ShowNormals,
  238.                     MatrixType Mat, int ViewInternal)
  239. {
  240.     int NumOfPoints, DontDraw;
  241.     PointType P, CenterP;
  242.     struct VertexStruct *V, *VStart;
  243.  
  244.     V = VStart = Pl -> V;
  245.     if (V == NULL) FatalError("ViewPolygon: Empty polygon to view\n");
  246.  
  247.     MatMultVecby4by4(P, V -> Pt, Mat);           /* Transform the first point. */
  248.     GGMyMove(P[0], P[1]);
  249.     DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal;      /* Draw next edge? */
  250.     GGMySetColor(Color);
  251.  
  252.     if (ShowNormals) {            /* If display of normal is required. */
  253.     NumOfPoints = 0;
  254.     PT_CLEAR(CenterP);
  255.     }
  256.  
  257.     do {
  258.     V = V -> Pnext;
  259.     if (ShowNormals) {
  260.         NumOfPoints++;
  261.         PT_ADD(CenterP, CenterP, V -> Pt);
  262.     }
  263.     MatMultVecby4by4(P, V -> Pt, Mat);
  264.     /* If edge is INTERNAL (Irit.h) and not ViewInternal - dont draw: */
  265.     if (DontDraw)
  266.          GGMyMove(P[0], P[1]);
  267.     else GGMyDraw(P[0], P[1]);
  268.  
  269.     DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal;  /* Draw next edge? */
  270.     } while (V != VStart && V -> Pnext != NULL);
  271.  
  272.     if (ShowNormals) {
  273.     PT_SCALE(CenterP, 1.0/NumOfPoints);        /* Estimate for normals. */
  274.     MatMultVecby4by4(P, CenterP, Mat);     /* Transform the first point. */
  275.     GGMyMove(P[0], P[1]);
  276.     PT_COPY(P, Pl -> Plane);
  277.     PT_SCALE(P, NormalsSize);
  278.     PT_ADD(CenterP, CenterP, P);
  279.     MatMultVecby4by4(P, CenterP, Mat);    /* Transform the second point. */
  280.     GGMySetColor(NormalsColor);
  281.     GGMyDraw(P[0], P[1]);
  282.     }
  283. }
  284.  
  285. /*****************************************************************************
  286. *  Routine to set the normals default values:                     *
  287. *****************************************************************************/
  288. void ViewSetNormals(RealType *Active, RealType *Size, RealType *Color)
  289. {
  290.     ViewNormals = !APX_EQ(*Active, 0.0);
  291.     NormalsSize = *Size;
  292.     NormalsColor = (int) *Color;
  293. }
  294.  
  295. #endif /* __MSDOS__ */
  296.