home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Module to handle viewing of objects in the ViewWindow. *
- * *
- * Written by: Gershon Elber IBM PC Ver 1.0, Jan. 1989 *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <conio.h>
- #include <graphics.h>
- #include <math.h>
- #include <setjmp.h>
- #include <string.h>
- #include "Program.h"
- #include "PostScrp.h"
- #include "GenMat.h"
- #include "Parser.h"
- #include "ViewObjL.h"
- #include "ViewObjG.h"
- #include "GraphGnG.h"
- #include "MouseDrv.h"
- #include "Gif_Lib.h"
-
- static FILE *PSFile = NULL; /* Used to save PostScript text file. */
- static jmp_buf LongJumpBuffer; /* Used in control C trapping. */
-
- /* 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.40, RED, "Rotate" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.72, GREEN, "Translate" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.04, CYAN, "Scale" },
- },
- { { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.1, BROWN, TRUE, "Screen Coords." },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.22, BLUE, TRUE, "Perspectiv" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.3, BLUE, FALSE, "Z" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.46, RED, FALSE, "X" }, /* Rot */
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.54, RED, FALSE, "Y" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.62, RED, FALSE, "Z" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.78, GREEN, FALSE, "X" }, /* Trans */
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.86, GREEN, FALSE, "Y" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 0.94, 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.26, MAGENTA,TRUE, "Depth cue" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.42, YELLOW, TRUE, "Save GIF" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.5, YELLOW, TRUE, "Save PS" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.62, YELLOW, TRUE, "Save Matrix" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.7, YELLOW, TRUE, "Reset Matrix" },
- { (SW_MIN_X + SW_MAX_X) / 2.0, SW_MAX_Y - 1.85, WHITE, TRUE, "Quit" },
- }
- };
-
- /* We support depth cues iff DepthCueFlag is TRUE: */
- #define MY_DOTTED_LINE (GlblDepthCue ? DOTTED_LINE : SOLID_LINE)
-
- /*****************************************************************************
- * Routine to interactively display geometric object(s) PObjList on the View *
- * window enable rotating/translating/scaling it using the Input Device. *
- *****************************************************************************/
- void InteractGeomObject(FileDescription **FD, int NumOfObjects, char **Objects)
- {
- switch (GlblTransformMode) {
- case TRANS_SCREEN:
- InteractMenu.SubWindows[0].Str = "Screen Coords.";
- break;
- case TRANS_OBJECT:
- InteractMenu.SubWindows[0].Str = "Object Coords.";
- break;
- }
-
- switch (GlblViewMode) {
- case VIEW_PERSPECTIVE:
- InteractMenu.SubWindows[1].Str = "Perspective";
- break;
- case VIEW_ORTHOGRAPHIC:
- InteractMenu.SubWindows[1].Str = "Orthographic";
- break;
- }
-
- if (GlblDepthCue)
- InteractMenu.SubWindows[10].Str = "Depth Cue";
- else InteractMenu.SubWindows[10].Str = "No Depth Cue";
-
- InteractDrawMenu(); /* Draw the transformation menu. */
- /* Get data from input device, interpret it, and display interactively: */
- InteractHandleInput(FD, NumOfObjects, Objects);
- }
-
- /*****************************************************************************
- * Routine to draw the Interactive Menu in the Menu window, using the *
- * InteractiveMenu structure defined above. *
- * It is assumed that string not inside of SubWindow will be of length 1. *
- *****************************************************************************/
- static void InteractDrawMenu(void)
- {
- int i;
- struct textsettingstype oldtext;
-
- gettextsettings(&oldtext);
- settextjustify(CENTER_TEXT, CENTER_TEXT); /* Draw strings centered. */
-
- GGClearMenuArea(); /* Clear the menu window. */
-
- for (i=0; i<INTERACT_NUM_OF_STRINGS; i++) {/* Draw the strings of struct.*/
- GGMySetColor(InteractMenu.Strings[i].Color);
- GGXYPutStr(InteractMenu.Strings[i].X,
- InteractMenu.Strings[i].Y,
- InteractMenu.Strings[i].Str);
- }
-
- for (i=0; i<INTERACT_NUM_OF_SUB_WINDOWS; i++) {/* Draw strct sub windows.*/
- 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)
- GGXYPutStr(InteractMenu.SubWindows[i].X,
- InteractMenu.SubWindows[i].Y,
- InteractMenu.SubWindows[i].Str);
- else {
- GGXYPutStr(InteractMenu.SubWindows[i].X -
- INTERACT_SUB_WINDOW_WIDTH - 0.025,
- InteractMenu.SubWindows[i].Y,
- InteractMenu.SubWindows[i].Str);
- 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 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(FileDescription **FD, int NumOfObj,
- char **Objects)
- {
- int i, UpdateView;
- double x, y, ChangeFactor;
- char *p, GifFileName[FILE_NAME_LEN];
- static char GifFileCount = '0';
- MatrixType Mat, OrigViewMat, OrigPerspMat;
-
- /* Save copy of original matrix, so we can recover if reset is requeired.*/
- GEN_COPY(OrigViewMat, GlblViewMat, sizeof(MatrixType));
- GEN_COPY(OrigPerspMat, GlblPerspMat, sizeof(MatrixType));
- switch (GlblViewMode) { /* Update the current view. */
- case VIEW_ORTHOGRAPHIC:
- GEN_COPY(CrntViewMat, GlblViewMat, sizeof(MatrixType));
- break;
- case VIEW_PERSPECTIVE:
- MultTwo4by4(CrntViewMat, GlblViewMat, GlblPerspMat);
- break;
- }
-
- GGClearViewArea(); /* Clear the view window. */
- ViewGeomObjectList(FD, NumOfObj, Objects); /* Display it for first time. */
-
- while (TRUE) {
- 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 (ABS(InteractMenu.SubWindows[i].Y - y) <
- INTERACT_SUB_WINDOW_HEIGHT &&
- ABS(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);
- continue;
- }
-
- UpdateView = TRUE;
- GenUnitMat(Mat); /* No transformation by default! */
-
- switch (i) {
- case 0: /* Its Coordinate system - toggle it. */
- switch (GlblTransformMode) {
- case TRANS_SCREEN:
- InteractUpdateMenu("Object Coords.", 0);
- GlblTransformMode = TRANS_OBJECT;
- break;
- case TRANS_OBJECT:
- InteractUpdateMenu("Screen Coords.", 0);
- GlblTransformMode = TRANS_SCREEN;
- break;
- }
- UpdateView = FALSE;
- break;
- case 1: /* Toggle Perspective/Orthographic view. */
- switch (GlblViewMode) {
- case VIEW_PERSPECTIVE:
- InteractUpdateMenu("Orthographic", 1);
- GlblViewMode = VIEW_ORTHOGRAPHIC;
- break;
- case VIEW_ORTHOGRAPHIC:
- InteractUpdateMenu("Perspective", 1);
- GlblViewMode = VIEW_PERSPECTIVE;
- break;
- }
- break;
- case 2: /* Set Perspective Screen Z point. */
- if (GlblViewMode != VIEW_PERSPECTIVE) {
- GGTone(1000, 100); /* Do some noise! */
- UpdateView = FALSE;
- break;
- }
- /* Make it between 0.5 and 1.5: */
- ChangeFactor = ChangeFactor / 2.0 + 1.0;
- GlblPerspMat[2][2] *= ChangeFactor;
- GlblPerspMat[2][3] *= ChangeFactor;
- GlblPerspMat[3][2] *= ChangeFactor;
- break;
- case 3: /* Its rotation along the X axis. */
- GenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 4: /* Its rotation along the Y axis. */
- GenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 5: /* Its rotation along the Z axis. */
- GenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
- break;
- case 6: /* Its translation along the X axis. */
- GenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0,
- Mat);
- break;
- case 7: /* Its translation along the Y axis. */
- GenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0,
- Mat);
- break;
- case 8: /* Its translation along the Z axis. */
- GenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR,
- Mat);
- break;
- case 9: /* 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 10: /* Toggle depth cueing. */
- GlblDepthCue = !GlblDepthCue;
- InteractUpdateMenu(GlblDepthCue ? "Depth Cue" : "No Depth Cue",
- 10);
- break;
- case 11: /* Generate GIF file from screen. */
- strcpy(GifFileName, GENERIC_GIF_FILE);
- if ((p = strchr(GifFileName, '#')) != NULL) {
- *p = GifFileCount;
- if (GifFileCount++ == '9') GifFileCount = '0';
- }
- if (DumpScreen(GifFileName, GraphDriver, GGGraphMode) != 0) {
- /* Something went wrong - let the user know about it. */
- GGTone(400, 300);
- GGTone(100, 300);
- }
- else GGTone(1000, 100);
- UpdateView = FALSE;
- break;
- case 12: /* Save view as PostScript file. */
- SavePostScript(FD, NumOfObj, Objects);
- UpdateView = FALSE;
- break;
- case 13: /* Save transformation matrix. */
- SaveCurrentMat();
- UpdateView = FALSE;
- break;
- case 14: /* Reset transformation matrix. */
- GEN_COPY(GlblViewMat, OrigViewMat, sizeof(MatrixType));
- GEN_COPY(GlblPerspMat, OrigPerspMat, sizeof(MatrixType));
- break;
- case 15:
- return; /* Its Quit. */
- default:
- GGTone(1000, 100); /* Do some noise! */
- UpdateView = FALSE;
- break;
- }
- if (UpdateView) {
- GGClearViewArea(); /* Clear the view window. */
-
- switch (GlblTransformMode) {/* Udpate the global viewing matrix. */
- case TRANS_SCREEN:
- MultTwo4by4(GlblViewMat, GlblViewMat, Mat);
- break;
- case TRANS_OBJECT:
- MultTwo4by4(GlblViewMat, Mat, GlblViewMat);
- break;
- }
-
- switch (GlblViewMode) { /* Update the current view. */
- case VIEW_ORTHOGRAPHIC:
- GEN_COPY(CrntViewMat, GlblViewMat, sizeof(MatrixType));
- break;
- case VIEW_PERSPECTIVE:
- MultTwo4by4(CrntViewMat, GlblViewMat, GlblPerspMat);
- break;
- }
-
- ViewGeomObjectList(FD, NumOfObj, Objects); /* And display it... */
- }
- }
- }
-
- /*****************************************************************************
- * Routine to update entry Entry with a new string Str. *
- *****************************************************************************/
- static void InteractUpdateMenu(char *Str, int Entry)
- {
- struct textsettingstype oldtext;
- struct viewporttype view;
-
- gettextsettings(&oldtext);
- settextjustify(CENTER_TEXT, CENTER_TEXT); /* Draw strings centered. */
-
- getviewsettings(&view);
- GGViewPortMenuArea();
-
- GGMySetColor(BLACK); /* Erase the old string. */
- GGXYPutStr(InteractMenu.SubWindows[Entry].X,
- InteractMenu.SubWindows[Entry].Y,
- InteractMenu.SubWindows[Entry].Str);
-
- InteractMenu.SubWindows[Entry].Str = Str; /* Update to new one. */
-
- GGMySetColor(InteractMenu.SubWindows[Entry].Color); /* And draw the new. */
- GGXYPutStr(InteractMenu.SubWindows[Entry].X,
- InteractMenu.SubWindows[Entry].Y,
- InteractMenu.SubWindows[Entry].Str);
-
- settextjustify(oldtext.horiz, oldtext.vert);
- setviewport(view.left, view.top, view.right, view.bottom, view.clip);
- }
-
- /*****************************************************************************
- * Routine to draw NumOfObjects given in Objects from FileDescription FD *
- * according to view matrix Mat. If NumOfObjects == 0 then all the objects *
- * are drawn. If NumEdges != 0 only the first NumEdges edges in each polygon *
- * are drawn. If InterFlag then INTERNAL edges (created by IRIT solid *
- * modeller) are also drawn. *
- *****************************************************************************/
- static void ViewGeomObjectList(FileDescription **FD, int NumOfObjects,
- char **Objects)
- {
- int i;
- ObjectStruct *PObject;
- struct linesettingstype savetype;
-
- getlinesettings(&savetype); /* Save original line setting. */
-
- GGMySetColor(RED); /* Make default color - RED. */
-
- if (setjmp(LongJumpBuffer) == 0) /* Its the setjmp itself call! */
- if (NumOfObjects > 0) /* There was something on command line... */
- for (i=0; i<NumOfObjects; i++) {
- if ((PObject = SearchObject(FD, *Objects)) ==
- (ObjectStruct *) NULL)
- printf("Given Object %s not found in data files\n",
- *Objects);
- else ViewOneObject(PObject);
- Objects++;
- }
- else {
- /* Draw all objects not in other object by scanning object trees.*/
- DrawAllObjects(FD); /* and drawing ones with Reference == 0. */
- }
-
- setlinestyle(savetype.linestyle, savetype.upattern, savetype.thickness);
- }
-
- /*****************************************************************************
- * Routine to save the current view trans. GlblViewMat to a generic mat file *
- *****************************************************************************/
- static void SaveCurrentMat(void)
- {
- int i, j;
- FILE *f;
- char *p, FileName[FILE_NAME_LEN];
- static char FileCount = '0';
-
- strcpy(FileName, GENERIC_MAT_FILE);
- if ((p = strchr(FileName, '#')) != NULL) {
- *p = FileCount;
- if (FileCount++ == '9') FileCount = '0';
- }
- if ((f = fopen(FileName, "wt")) == NULL) {
- GGTone(700, 200);
- return;
- }
-
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) fprintf(f, "%12lf ", GlblViewMat[i][j]);
- fprintf(f, "\n");
- }
-
- if (GlblViewMode == VIEW_PERSPECTIVE) {
- fprintf(f, "\n");
- for (i=0; i<4; i++) {
- for (j=0; j<4; j++) fprintf(f, "%12lf ", GlblPerspMat[i][j]);
- fprintf(f, "\n");
- }
- }
-
- fclose(f);
- }
-
- /*****************************************************************************
- * Routine to search for an object in the File descriptions FD. Note that if *
- * an object exists more than once only the first will be returned. If none *
- * is found then NULL is returned, else a pointer to that object struct. *
- *****************************************************************************/
- static ObjectStruct *SearchObject(FileDescription **FD, char *Object)
- {
- BinTree *PBinTree;
-
- while (*FD) {
- if ((PBinTree = GetBinTree(Object, (*FD++) -> ObjectPointer)) !=
- (BinTree *) NULL)
- return PBinTree -> Data.PObject;
- }
- return (ObjectStruct *) NULL;
- }
-
- /*****************************************************************************
- * Routine to draw all the objects not in other objects... *
- * by scanning all the object trees and drawing the objects with Reference==0 *
- * meaning nobody referred to them yet... *
- *****************************************************************************/
- static void DrawAllObjects(FileDescription **FD)
- {
- while (*FD) VisitObjectTree((*FD++) -> ObjectPointer);
- }
-
- /*****************************************************************************
- * Routine to draw all the objects not in other objects... *
- * by scanning all the object in tree PBinTree and drawing the objects with *
- * Reference==0, meaning nobody referred to them yet... *
- *****************************************************************************/
- static void VisitObjectTree(BinTree *PBinTree)
- {
- if (PBinTree == (BinTree *) NULL) return;
-
- VisitObjectTree(PBinTree -> right);
-
- if (MoreFlag == 1)
- printf("Drawing object %s\n", PBinTree -> Name);
- ViewOneObject(PBinTree -> Data.PObject);
-
- VisitObjectTree(PBinTree -> left);
- }
-
- /*****************************************************************************
- * Routine to draw one object Object, using the Matrix transform Mat. *
- *****************************************************************************/
- static void ViewOneObject(ObjectStruct *PObject)
- {
- PolygonStruct *PList = PObject -> PPolygon;
-
- SetDrawColor(PObject -> Color); /* Default color for object. */
-
- while (PList) {
- ViewOnePolygon(PList);
- PList = PList -> Pnext;
- }
- }
-
- /*****************************************************************************
- * Routine to draw one polygon, using the Matrix transform Mat. *
- * Note this is the routine that makes the real drawing... *
- *****************************************************************************/
- static void ViewOnePolygon(PolygonStruct *PPolygon)
- {
- int i, Count, DrawNextEdge, NumOfVertices;
- float MappedNormal[3], PolyNormal[3];
- VertexStruct *PList = PPolygon -> PVertex;
-
- TestQuitView();
-
- Count = NumEdges;
-
- if (PList == NULL) return;
-
- switch (PPolygon -> PolyType) {
- case POINTLIST:
- while (PList) {
- MyMoveTo(PList -> Coord);
- MyDrawTo(PList -> Coord);
- PList = PList -> Pnext;
- }
- break;
- case POLYLINE:
- MyMoveTo(PList -> Coord);
- DrawNextEdge = !PList -> Internal;
- PList = PList -> Pnext;
-
- while (PList) {
- if (DrawNextEdge || InterFlag)
- MyDrawTo(PList -> Coord);
- else MyMoveTo(PList -> Coord);
-
- if (DrawVNormalsFlag && PList -> HasNormal) {
- for (i=0; i<3; i++) MappedNormal[i] =
- PList -> Coord[i] + PList -> Normal[i];
- MyDrawTo(MappedNormal);
- MyMoveTo(PList -> Coord);
- }
- DrawNextEdge = !PList -> Internal;
- PList = PList -> Pnext;
- }
- break;
- case POLYGON:
- if (DrawPNormalsFlag && PPolygon->HasPlane)
- {
- for (i=0; i<3; i++) PolyNormal[i] = PList -> Coord[i];
- NumOfVertices = 1;
- }
-
- MyMoveTo(PList -> Coord);
- DrawNextEdge = !PList -> Internal;
- PList = PList -> Pnext;
-
- while (PList) {
- if (DrawNextEdge || InterFlag)
- MyDrawTo(PList -> Coord);
- else MyMoveTo(PList -> Coord);
-
- if (DrawVNormalsFlag && PList -> HasNormal) {
- for (i=0; i<3; i++) MappedNormal[i] =
- PList -> Coord[i] + PList -> Normal[i];
- i = ClosedObject;
- ClosedObject = FALSE;
- MyDrawTo(MappedNormal);
- MyMoveTo(PList -> Coord);
- ClosedObject = i;
- }
-
- if (DrawPNormalsFlag && PPolygon->HasPlane)
- {
- for (i=0; i<3; i++) PolyNormal[i] += PList -> Coord[i];
- NumOfVertices++;
- }
- /* If -e option specified #Edges to draw. */
- if (!(--Count)) return;
- DrawNextEdge = !PList -> Internal;
- PList = PList -> Pnext;
- }
-
- /* Close polygon by drawing a line to first vertex. */
- if (DrawNextEdge || InterFlag)
- MyDrawTo(PPolygon -> PVertex -> Coord);
-
- if (DrawPNormalsFlag && PPolygon->HasPlane)
- {
- for (i=0; i<3; i++) PolyNormal[i] /= NumOfVertices;
- MyMoveTo(PolyNormal);
- for (i=0; i<3; i++) PolyNormal[i] += PPolygon->Plane[i];
- i = ClosedObject;
- ClosedObject = FALSE;
- MyDrawTo(PolyNormal);
- ClosedObject = i;
- }
- break;
- }
- }
-
- static double LastCoord[3]; /* Used to store last point we moved/draw to. */
-
- /*****************************************************************************
- * Routine to mave to 3D point given as Coord[3], using Mat transform. *
- *****************************************************************************/
- static void MyMoveTo(float Coord[3])
- {
- MultVecby4by4(LastCoord, Coord, CrntViewMat); /* Set last point coord. */
- }
-
- /*****************************************************************************
- * Routine to draw to 3D point given as Coord[3], using Mat transform, from *
- * the last point we moved to. *
- *****************************************************************************/
- static void MyDrawTo(float Coord[3])
- {
- double NewCoord[3], MiddleCoord[3], t;
-
- MultVecby4by4(NewCoord, Coord, CrntViewMat); /* Set last point coord. */
- if (ClosedObject && NewCoord[2] < LastCoord[2]) {
- GEN_COPY(LastCoord, NewCoord, 3 * sizeof(double));
- return;
- }
-
- /* Implementation of simple depth cue - if line is >Z or <Z ... */
- if (LastCoord[2] <= 0.0 && NewCoord[2] <= 0.0) {
- setlinestyle(MY_DOTTED_LINE, 0, NORM_WIDTH);
- GGMyMove(LastCoord[0], LastCoord[1]);
- GGMyDraw(NewCoord[0], NewCoord[1]); /* DRAW! */
- }
- else
- if (LastCoord[2] >= 0.0 && NewCoord[2] >= 0.0 ||
- ABS(LastCoord[2] - NewCoord[2]) < EPSILON) {
- setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
- GGMyMove(LastCoord[0], LastCoord[1]);
- GGMyDraw(NewCoord[0], NewCoord[1]); /* DRAW! */
- }
- else { /* Line intersect Z = 0 plane. */
- t = LastCoord[2] / (LastCoord[2] - NewCoord[2]);
- MiddleCoord[0] = LastCoord[0] * (1.0 - t) + NewCoord[0] * t;
- MiddleCoord[1] = LastCoord[1] * (1.0 - t) + NewCoord[1] * t;
- setlinestyle(SOLID_LINE, 0, NORM_WIDTH); /* Draw the >Z part: */
- if (LastCoord[2] > 0.0) {
- GGMyMove(LastCoord[0], LastCoord[1]);
- GGMyDraw(MiddleCoord[0], MiddleCoord[1]); /* DRAW! */
- }
- else {
- GGMyMove(MiddleCoord[0], MiddleCoord[1]);
- GGMyDraw(NewCoord[0], NewCoord[1]); /* DRAW! */
- }
- setlinestyle(MY_DOTTED_LINE, 0, NORM_WIDTH); /* Draw the <Z part: */
- if (LastCoord[2] < 0.0) {
- GGMyMove(LastCoord[0], LastCoord[1]);
- GGMyDraw(MiddleCoord[0], MiddleCoord[1]); /* DRAW! */
- }
- else {
- GGMyMove(MiddleCoord[0], MiddleCoord[1]);
- GGMyDraw(NewCoord[0], NewCoord[1]); /* DRAW! */
- }
- }
-
- GEN_COPY(LastCoord, NewCoord, 3 * sizeof(double)); /* Set current point. */
- }
-
- /*****************************************************************************
- * Routine to set current drawing color to given RGB values: *
- * Currently only 8 colors are supported: *
- *****************************************************************************/
- static void SetDrawColor(int Color)
- {
- GGMySetColor(Color);
- }
-
- /*****************************************************************************
- * Routine to test if quit display event - occured - SPACE was hit on *
- * keyboard or right button was clicked on mouse. *
- *****************************************************************************/
- static void TestQuitView(void)
- {
- int x, y, Buttons;
-
- if (kbhit() && getch() == ' ')
- longjmp(LongJumpBuffer, 1); /* Jump to... */
-
- if (MouseExists && MouseQueryBuffer()) {
- MouseGetBuffer(&x, &y, &Buttons);
- if (Buttons & 0x02) longjmp(LongJumpBuffer, 1); /* Jump to... */
- }
- }
-