home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * "Irit" - the 3d polygonal solid modeller. *
- * *
- * Written by: Gershon Elber Unix - X11 Ver 0.1, Mar. 1990 *
- ******************************************************************************
- * Module to handle viewing of objects in the ViewWindow. *
- *****************************************************************************/
-
- #ifndef __MSDOS__
-
- #include <stdio.h>
- #include <math.h>
- #include "program.h"
- #include "windowsl.h"
- #include "windowsg.h"
- #include "viewobjl.h"
- #include "viewobjg.h"
- #include "graphgng.h"
- #include "objects.h"
-
- #include "xgraphic.h"
-
- static int ViewNormals = FALSE, NormalsColor = 1, /* View normals to object. */
- QuitView = FALSE;
- static RealType NormalsSize = 0.1;
- static ObjectStruct *ActiveObjList = NULL; /* Currently displayed objects. */
-
- /*****************************************************************************
- * Routine to interactively display geometric object(s) PObjList on the View *
- * window enable rotating/translating/scaling it using the Input Device. *
- *****************************************************************************/
- void InteractGeomObject(ObjectStruct *PObjList, RealType *UpdateGlblMat)
- {
- struct ObjectStruct *ViewMat;
- MatrixType ViewMatCopy; /* Save original transformation to recover. */
-
- if (!IS_OLST_OBJ(PObjList))
- FatalError("InteractGeomObject: Not object list object!\n");
-
- if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No view transformation matrix VIEW_MAT!", RED);
- return;
- }
- else if (!IS_MAT_OBJ(ViewMat)) {
- WndwInputWindowPutStr(
- "VIEW_MAT object was modified (not matrix object)", RED);
- return;
- }
- MAT_COPY(ViewMatCopy, ViewMat -> U.Mat);
-
- /* Get data from input device, interpret it, and display interactively: */
- InteractHandleInput(PObjList, ViewMat -> U.Mat);
-
- if (!APX_EQ(*UpdateGlblMat, 0.0))
- MAT_COPY(ViewMat -> U.Mat, ViewMatCopy); /* Recover. */
- }
-
- /*****************************************************************************
- * Routine to handle data from the input device (keyboard, mouse etc.) - *
- * clip it against the sub windows of the interactive menu and perform the *
- * required transfomation, by updating the global view matrix object VIEW_MAT *
- * The input data in the Rotation/Translation/Scaling sub windows is used *
- * (horizontal distance from sub window center) to set amount of change. *
- *****************************************************************************/
- static void InteractHandleInput(ObjectStruct *PObjList, MatrixType GlblViewMat)
- {
- int i, UpdateView, ScreenCoord = TRUE;
- char *ToggleStr;
- RealType x, y, ChangeFactor;
- MatrixType Mat;
-
- ActiveObjList = PObjList;
-
- QuitView = FALSE;
- UpdateInteractHandleInput(); /* Display it for the first time. */
-
- while (TRUE) {
- QuitView = FALSE;
-
- UpdateView = TRUE;
-
- switch (GetGraphicEvent(&ChangeFactor, &ToggleStr)) {
- case EVENT_SCR_OBJ_TGL: /* Its Coordinate system - toggle it. */
- ScreenCoord = *ToggleStr == 'S';
- UpdateView = FALSE;
- break;
- case EVENT_ROTATE_X: /* Its rotation along the X axis. */
- MatGenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case EVENT_ROTATE_Y: /* Its rotation along the Y axis. */
- MatGenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case EVENT_ROTATE_Z: /* Its rotation along the Z axis. */
- MatGenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case EVENT_TRANSLATE_X: /* Its translation along the X axis. */
- MatGenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0,
- Mat);
- break;
- case EVENT_TRANSLATE_Y: /* Its translation along the Y axis. */
- MatGenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0,
- Mat);
- break;
- case EVENT_TRANSLATE_Z: /* Its translation along the Z axis. */
- MatGenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR,
- Mat);
- break;
- case EVENT_SCALE: /* Its scaling along all axes. */
- if (ChangeFactor > 0.0) /* Make it around 1... */
- ChangeFactor = ChangeFactor * MAX_SCALE_FACTOR + 1.0;
- else ChangeFactor = 1.0 /
- (-ChangeFactor * MAX_SCALE_FACTOR + 1.0);
- MatGenMatScale(ChangeFactor, ChangeFactor, ChangeFactor, Mat);
- break;
- case EVENT_QUIT:
- ActiveObjList = NULL;
- return; /* Its Quit. */
- default:
- FatalError("InteractHandleInput: Undefine input type, exit\n");
- }
- if (UpdateView) {
- if (ScreenCoord) /* Udpate the global viewing matrix. */
- MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
- else MatMultTwo4by4(GlblViewMat, Mat, GlblViewMat);
- UpdateInteractHandleInput();
- }
- }
- }
-
- /*****************************************************************************
- * Routine to update the viewing screen. On unix systems this routine may *
- * be invoked when X sends expose event to this program (see xgrphgen.c). *
- * In MSDOS this routine is static and been called from InteractHandleInput *
- * above routine only. *
- *****************************************************************************/
- void UpdateInteractHandleInput(void)
- {
- GGClearAllScreen();
- if (ActiveObjList != NULL)
- ViewGeomObjectList(ActiveObjList); /* And display it... */
- }
-
- /*****************************************************************************
- * Routine to display the geometric objects in PObjList, by simply calling *
- * ViewGeomObject on all of them. PObjList must be of type OBJ_LIST_OBJ. *
- *****************************************************************************/
- static void ViewGeomObjectList(ObjectStruct *PObjList)
- {
- int Param = 0;
- struct ObjectStruct *PObj;
- char Line[LINE_LEN];
-
- while ((PObj = PObjList -> U.PObjList[Param]) != NULL &&
- Param++ < MAX_OBJ_LIST && !QuitView) {
- if (!IS_GEOM_OBJ(PObj)) {
- sprintf(Line, "Cannt display none geometric object %s, ignored",
- PObj -> Name);
- WndwInputWindowPutStr(Line, RED);
- continue;
- }
- ViewGeomObject(PObj);
- }
- }
-
- /*****************************************************************************
- * Routine to fetch the internal parameter from the INTERNAL object. *
- *****************************************************************************/
- static int GetInternal(void)
- {
- int Internal;
- struct ObjectStruct *PObj = GetObject("INTERNAL");
-
- if (PObj == NULL || !IS_NUM_OBJ(PObj)) {
- WndwInputWindowPutStr("No numeric object name INTERNAL is defined",
- RED);
- Internal = DEFAULT_INTERNAL;
- }
- else Internal = !APX_EQ((PObj -> U.R), 0.0);
-
- return Internal;
- }
-
- /*****************************************************************************
- * Routine to display the geometric object PObj on the View Window: *
- * Uses the global view transformation matrix ViewMat as view point. *
- *****************************************************************************/
- void ViewGeomObject(ObjectStruct *PObj)
- {
- int Color, ShowNormals, ViewInternal = GetInternal();
- struct PolygonStruct *Pl;
- struct ObjectStruct *ViewMat;
-
- QuitView = FALSE;
-
- if (!IS_GEOM_OBJ(PObj))
- FatalError("ViewGeomObject: Not geometric object!\n");
-
- Pl = PObj -> U.Pl;
-
- if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No view transformation matrix VIEW_MAT!", RED);
- return;
- }
- else if (!IS_MAT_OBJ(ViewMat)) {
- WndwInputWindowPutStr(
- "VIEW_MAT object was modified (not matrix object)\n", RED);
- return;
- }
-
- Color = GET_OBJECT_COLOR(PObj);
- ShowNormals = (ViewNormals && !IS_POLYLINE_GEOM_OBJ(PObj));
-
- while (Pl && !QuitView) {
- ViewPolygon(Pl, Color, ShowNormals, ViewMat -> U.Mat, ViewInternal);
- Pl = Pl -> Pnext;
- TestQuitView(); /* if break display in the middle - Set QuitView. */
- }
-
- GraphicFlush();
- }
-
- /*****************************************************************************
- * Routine to test if quit display event - occured - *
- * Right button was clicked on mouse. *
- *****************************************************************************/
- static void TestQuitView(void)
- {
- QuitView = IsAbortKeyPressed();
- }
-
- /*****************************************************************************
- * Routine to display one polygon on the view window using the matrix Mat as *
- * a transformation matrix. *
- *****************************************************************************/
- static void ViewPolygon(PolygonStruct *Pl, int Color, int ShowNormals,
- MatrixType Mat, int ViewInternal)
- {
- int NumOfPoints, DontDraw;
- PointType P, CenterP;
- struct VertexStruct *V, *VStart;
-
- V = VStart = Pl -> V;
- if (V == NULL) FatalError("ViewPolygon: Empty polygon to view\n");
-
- MatMultVecby4by4(P, V -> Pt, Mat); /* Transform the first point. */
- GGMyMove(P[0], P[1]);
- DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal; /* Draw next edge? */
- GGMySetColor(Color);
-
- if (ShowNormals) { /* If display of normal is required. */
- NumOfPoints = 0;
- PT_CLEAR(CenterP);
- }
-
- do {
- V = V -> Pnext;
- if (ShowNormals) {
- NumOfPoints++;
- PT_ADD(CenterP, CenterP, V -> Pt);
- }
- MatMultVecby4by4(P, V -> Pt, Mat);
- /* If edge is INTERNAL (Irit.h) and not ViewInternal - dont draw: */
- if (DontDraw)
- GGMyMove(P[0], P[1]);
- else GGMyDraw(P[0], P[1]);
-
- DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal; /* Draw next edge? */
- } while (V != VStart && V -> Pnext != NULL);
-
- if (ShowNormals) {
- PT_SCALE(CenterP, 1.0/NumOfPoints); /* Estimate for normals. */
- MatMultVecby4by4(P, CenterP, Mat); /* Transform the first point. */
- GGMyMove(P[0], P[1]);
- PT_COPY(P, Pl -> Plane);
- PT_SCALE(P, NormalsSize);
- PT_ADD(CenterP, CenterP, P);
- MatMultVecby4by4(P, CenterP, Mat); /* Transform the second point. */
- GGMySetColor(NormalsColor);
- GGMyDraw(P[0], P[1]);
- }
- }
-
- /*****************************************************************************
- * Routine to set the normals default values: *
- *****************************************************************************/
- void ViewSetNormals(RealType *Active, RealType *Size, RealType *Color)
- {
- ViewNormals = !APX_EQ(*Active, 0.0);
- NormalsSize = *Size;
- NormalsColor = (int) *Color;
- }
-
- #endif /* __MSDOS__ */
-