home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Routines to set and transform the view matrix (type MatrixType): *
- * 1. Rotate about X, Y or Z axes. *
- * 2. Scale (same to all axes). *
- * 3. Translate about X, Y or Z axes. *
- * *
- * Written by: Gershon Elber Ver 0.1, Apr. 1988 *
- *****************************************************************************/
-
- #include <graphics.h>
- #include <math.h>
- #include <stdio.h>
- #include "Program.h"
- #include "Expr2TrG.h"
- #include "GenMat.h"
- #include "GraphGnG.h"
- #include "GraphGnL.h" /* Needs the sizes of windows, so be careful! */
- #include "ViewObj.h"
- #include "MouseDrv.h"
-
- /* Interactive mode menu set up structure is define below (See ViewObjL.H): */
- InteractWindowStruct InteractMenu = {
- { { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.2, RED, "Rotate" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.6, GREEN, "Translate" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.0, CYAN, "Scale" },
- },
- { { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.1, YELLOW, TRUE, "Screen Coords." },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.3, RED, FALSE, "X" }, /* Rot. */
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.4, RED, FALSE, "Y" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.5, RED, FALSE, "Z" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.7, GREEN, FALSE, "X" }, /* Trans. */
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.8, GREEN, FALSE, "Y" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.9, GREEN, FALSE, "Z" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.1, CYAN, FALSE, "" }, /* Scale. */
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.25, YELLOW, TRUE, "Save Matrix" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.4, YELLOW, TRUE, "Reset Matrix" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.8, WHITE, TRUE, "Quit" },
- }
- };
-
- static void SaveCurrentMat(MatrixType TransMat);
-
- /*****************************************************************************
- * Routine to draw the Interactive Menu in the Status window, using the *
- * InteractiveMenu structure defined above. *
- * It is assumed that string not inside of SubWindow will be of length 1. *
- *****************************************************************************/
- void InteractDrawMenu(void)
- {
- int i;
- struct textsettingstype oldtext;
-
- gettextsettings(&oldtext);
- settextjustify(CENTER_TEXT, CENTER_TEXT); /* Draw strings centered. */
-
- GGClearMenuArea(); /* Clear the status window. */
-
- for (i=0; i<INTERACT_NUM_OF_STRINGS; i++) { /* Draw strings of struct. */
- GGMySetColor(InteractMenu.Strings[i].Color);
- GGPutMsgXY(InteractMenu.Strings[i].Str,
- InteractMenu.Strings[i].X,
- InteractMenu.Strings[i].Y);
- }
-
- for (i=0; i<INTERACT_NUM_OF_SUB_WINDOWS; i++) {/* Draw struct sub wndws. */
- GGMySetColor(InteractMenu.SubWindows[i].Color);
- /* Draw the frame of the SubWindow: */
- GGMyMove(InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
- InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
- GGMyDraw(InteractMenu.SubWindows[i].X + INTERACT_SUB_WINDOW_WIDTH,
- InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
- GGMyDraw(InteractMenu.SubWindows[i].X + INTERACT_SUB_WINDOW_WIDTH,
- InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT);
- GGMyDraw(InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
- InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT);
- GGMyDraw(InteractMenu.SubWindows[i].X - INTERACT_SUB_WINDOW_WIDTH,
- InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
-
- /* Now the strings inside (and if outside, a middle vertical line): */
- if (InteractMenu.SubWindows[i].TextInside)
- GGPutMsgXY(InteractMenu.SubWindows[i].Str,
- InteractMenu.SubWindows[i].X,
- InteractMenu.SubWindows[i].Y);
-
- else {
- GGPutMsgXY(InteractMenu.SubWindows[i].Str,
- InteractMenu.SubWindows[i].X -
- INTERACT_SUB_WINDOW_WIDTH - 0.025,
- InteractMenu.SubWindows[i].Y);
- GGMyMove(InteractMenu.SubWindows[i].X,
- InteractMenu.SubWindows[i].Y - INTERACT_SUB_WINDOW_HEIGHT);
- GGMyDraw(InteractMenu.SubWindows[i].X,
- InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT);
- }
- }
-
- settextjustify(oldtext.horiz, oldtext.vert);
- }
-
- /*****************************************************************************
- * 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 given matrix TransMat. *
- * The input data in the Rotation/Translation/Scaling sub windows is used *
- * (horizontal distance from sub window center) to set amount of change. *
- * Return TRUE if quit was signalled... *
- *****************************************************************************/
- int InteractHandleInput(MatrixType TransMat, MatrixType OrigMat)
- {
- int i, j, UpdateView, ScreenCoord;
- double x, y, ChangeFactor;
- MatrixType Mat;
-
- ScreenCoord = (InteractMenu.SubWindows[0].Str[0] == 'S');
- do {
- MouseFlushBuffer(); /* Flush out any duplicated points picked. */
- GGGetPoint(&x, &y); /* Get coordinates from pick device. */
- for (i=0; i<INTERACT_NUM_OF_SUB_WINDOWS; i++)/* Test all sub windows.*/
- if (fabs(InteractMenu.SubWindows[i].Y - y) <
- INTERACT_SUB_WINDOW_HEIGHT &&
- fabs(InteractMenu.SubWindows[i].X - x) <
- INTERACT_SUB_WINDOW_WIDTH)
- break; /* The picked point is in this window! */
-
- ChangeFactor = (x - InteractMenu.SubWindows[i].X) //* Between -1..1. */
- INTERACT_SUB_WINDOW_WIDTH;
- if (i >= INTERACT_NUM_OF_SUB_WINDOWS) {
- GGTone(1000, 100);
- GGTone(1500, 100);
- GGTone(1000, 100);
- UpdateView = FALSE;
- continue;
- }
-
- UpdateView = TRUE;
-
- switch (i) {
- case 0: /* Its Coordinate system - toggle it. */
- if (ScreenCoord) {
- InteractMenu.SubWindows[0].Str = "Object Coords.";
- ScreenCoord = FALSE;
- }
- else {
- InteractMenu.SubWindows[0].Str = "Screen Coords.";
- ScreenCoord = TRUE;
- }
- InteractDrawMenu(); /* Must update the menu on screen. */
- UpdateView = FALSE;
- break;
- case 1: /* Its rotation along the X axis. */
- GenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 2: /* Its rotation along the Y axis. */
- GenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 3: /* Its rotation along the Z axis. */
- GenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 4: /* Its translation along the X axis. */
- GenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0,
- Mat);
- break;
- case 5: /* Its translation along the Y axis. */
- GenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0,
- Mat);
- break;
- case 6: /* Its translation along the Z axis. */
- GenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR,
- Mat);
- break;
- case 7: /* 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);
- GenMatScale(ChangeFactor, ChangeFactor, ChangeFactor, Mat);
- break;
- case 8: /* Save transformation matrix. */
- SaveCurrentMat(TransMat);
- UpdateView = FALSE;
- break;
- case 9: /* Reset transformation matrix. */
- for (i=0; i<4; i++)
- for (j=0; j<4; j++) TransMat[i][j] = OrigMat[i][j];
- GenUnitMat(Mat); /* No transformation! */
- break;
- case 10:
- return TRUE; /* Its Quit. */
- default:
- GGTone(1000, 100); /* Do some noise! */
- UpdateView = FALSE;
- break;
- }
- }
- while (!UpdateView);
-
- if (ScreenCoord) /* Udpate the global viewing matrix. */
- MultTwo4by4(TransMat, TransMat, Mat);
- else MultTwo4by4(TransMat, Mat, TransMat);
-
- return FALSE;
- }
-
- /*****************************************************************************
- * Routine to save the current view trans. GlblViewMat to a generic mat file *
- *****************************************************************************/
- static void SaveCurrentMat(MatrixType TransMat)
- {
- int i, j;
- FILE *f;
-
- if ((f = fopen(GENERIC_MAT_FILE, "wt")) == NULL) {
- GGTone(700, 200);
- return;
- }
-
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) fprintf(f, "%12lf ", TransMat[i][j]);
- fprintf(f, "\n");
- }
-
- fclose(f);
- }
-