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. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <math.h>
- #include "program.h"
- #include "attribut.h"
- #include "graphgen.h"
- #include "objects.h"
- #include "freeform.h"
- #include "geomat3d.h"
- #include "primitiv.h"
- #include "windows.h"
- #include "viewobj.h"
- #include "graphgen.h"
-
- #define MAX_ROTATE_ANGLE 45.0 /* Maximum rates used by interact mode. */
- #define MAX_TRANSLATE_FACTOR 2.0
- #define MAX_SCALE_FACTOR 2.0
-
- static int
- ViewNormals = FALSE,
- ClosedObject = FALSE,
- SupportClosedObject = FALSE,
- NormalsColor = 1, /* View normals to object. */
- QuitView = FALSE;
- static RealType
- LastCoord[3], /* Used to store last point we moved/draw to. */
- NormalsSize = 0.1;
- static ObjectStruct
- *ActiveObjList = NULL; /* Currently displayed objects. */
-
- /* Prototypes for the View Object module: */
- static void InteractHandleInput(ObjectStruct *PObjList,
- MatrixType GlblViewMat, MatrixType GlblPrspMat);
- static MatrixType *ComputeCrntViewMatrix(void);
- static void ViewGeomObjectList(ObjectStruct *PObjList);
- static int GetInternal(void);
- static void ViewCagdPolyline(CagdPolylineStruct *Pl, int Color,
- MatrixType Mat);
- static void TestQuitView(void);
- static void ViewPolygon(PolygonStruct *Pl, int Color, int IsPolyline,
- MatrixType Mat, int ViewInternal);
- static void DepthCueMoveTo(RealType Coord[3]);
- static void DepthCueDrawTo(RealType NewCoord[3]);
-
- #ifdef __GL__
- static void DrawPolygonSolid(PolygonStruct *PPolygon, MatrixType Mat);
- #endif /* __GL__ */
-
- /*****************************************************************************
- * Routine to interactively display geometric object(s) PObj on the View *
- * window enable rotating/translating/scaling it using the Input Device. *
- *****************************************************************************/
- void InteractPolyObject(ObjectStruct *PObj, RealType *UpdateGlblMat)
- {
- ObjectStruct *ViewMat, *PrspMat;
- MatrixType ViewMatCopy, PrspMatCopy; /* Save original trans. to recover. */
-
- if (!GlblDoGraphics) return;
-
- if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No view transformation matrix VIEW_MAT!");
- return;
- }
- else if (!IS_MAT_OBJ(ViewMat)) {
- WndwInputWindowPutStr(
- "VIEW_MAT object was modified (not matrix object)");
- return;
- }
- MAT_COPY(ViewMatCopy, ViewMat -> U.Mat);
-
- if ((PrspMat = GetObject("PRSP_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No perspective transformation matrix PRSP_MAT!");
- return;
- }
- else if (!IS_MAT_OBJ(PrspMat)) {
- WndwInputWindowPutStr(
- "PRSP_MAT object was modified (not matrix object)");
- return;
- }
- MAT_COPY(PrspMatCopy, PrspMat -> U.Mat);
-
- /* Get data from input device, interpret it, and display interactively: */
- InteractHandleInput(PObj, ViewMat -> U.Mat, PrspMat -> U.Mat);
-
- if (!APX_EQ(*UpdateGlblMat, 0.0)) {
- MAT_COPY(ViewMat -> U.Mat, ViewMatCopy); /* Recover. */
- MAT_COPY(PrspMat -> U.Mat, PrspMatCopy);
- }
- }
-
- /*****************************************************************************
- * 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, MatrixType GlblPrspMat)
- {
- int UpdateView;
- RealType ChangeFactor;
- MatrixType Mat, OrigViewMat, OrigPrspMat;
- #if !defined(__MSDOS__) && !defined(DJGCC)
- long WinID, DispID, ColorMapID;
- #endif /* !__MSDOS__ && !DJGCC */
-
- /* Save copy of original matrix, so we can recover if reset is required. */
- GEN_COPY(OrigViewMat, GlblViewMat, sizeof(MatrixType));
- GEN_COPY(OrigPrspMat, GlblPrspMat, sizeof(MatrixType));
-
- ActiveObjList = PObjList;
-
- QuitView = FALSE;
-
- #ifdef __MSDOS__
- IntrWndwPop(TransWindowID, TRUE, TRUE);
- #endif /* __MSDOS__ */
-
- #if defined(__MSDOS__) || defined(DJGCC)
- GGClearViewArea();
-
- /* Set the async. function for intr_lib to refresh the view window. */
- IntrWndwSetRefreshFunc(ViewWindowID,
- (IntrIntFunc) UpdateInteractHandleInput);
- #endif /* __MSDOS__ || DJGCC */
-
- UpdateInteractHandleInput(); /* Display it for the first time. */
-
- while (TRUE) {
- QuitView = FALSE;
-
- UpdateView = TRUE;
-
- switch (GGGetGraphicEvent(&ChangeFactor)) {
- case EVENT_SCR_OBJ_TGL: /* Its Coordinate system - toggle it. */
- UpdateView = FALSE;
- break;
- case EVENT_PERS_ORTHO_TGL: /* Its View mode - toggle it. */
- MatGenUnitMat(Mat);
- break;
- case EVENT_PERS_ORTHO_Z: /* Its Perspective Z focal point modif. */
- 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;
- GlblPrspMat[2][2] *= ChangeFactor;
- GlblPrspMat[2][3] *= ChangeFactor;
- GlblPrspMat[3][2] *= ChangeFactor;
- MatGenUnitMat(Mat);
- 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_DEPTH_CUE:
- if (!GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
- MatGenUnitMat(Mat);
- break;
- #ifdef __GL__ /* Only on GL library systems. */
- case EVENT_DRAW_SOLID:
- MatGenUnitMat(Mat);
- break;
- #else
- case EVENT_DRAW_SOLID:
- #endif
- case EVENT_SAVE_GIF:
- case EVENT_SAVE_PS:
- case EVENT_SAVE_MATRIX:
- GGTone(800, 100);
- GGTone(400, 200);
- UpdateView = FALSE;
- break;
- case EVENT_RESET_MATRIX:
- GEN_COPY(GlblViewMat, OrigViewMat, sizeof(MatrixType));
- GEN_COPY(GlblPrspMat, OrigPrspMat, sizeof(MatrixType));
- MatGenUnitMat(Mat);
- break;
- case EVENT_QUIT:
- ActiveObjList = NULL;
- #ifdef __MSDOS__
- IntrWndwPop(StatusWindowID, TRUE, TRUE);
- #endif /* __MSDOS__ */
- return; /* Its Quit. */
- default:
- FatalError("InteractHandleInput: Undefine input type, exit\n");
- }
- if (UpdateView) {
- switch (GlblTransformMode) {/* Udpate the global viewing matrix. */
- case TRANS_SCREEN:
- MatMultTwo4by4(GlblViewMat, GlblViewMat, Mat);
- break;
- case TRANS_OBJECT:
- MatMultTwo4by4(GlblViewMat, Mat, GlblViewMat);
- break;
- }
-
- #if defined(__MSDOS__) || defined(DJGCC)
- GGClearViewArea();
- #endif /* __MSDOS__ || DJGCC */
- UpdateInteractHandleInput();
- }
- }
- }
-
- /*****************************************************************************
- * Compute the current view using VIEW_MAT and PRSP_MAT matrices. *
- *****************************************************************************/
- static MatrixType *ComputeCrntViewMatrix(void)
- {
- static MatrixType CrntViewMat;
- ObjectStruct *ViewMat, *PrspMat;
-
- if ((ViewMat = GetObject("VIEW_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No view transformation matrix VIEW_MAT!");
- return NULL;
- }
- else if (!IS_MAT_OBJ(ViewMat)) {
- WndwInputWindowPutStr(
- "VIEW_MAT object was modified (not matrix object)");
- return NULL;
- }
-
- if ((PrspMat = GetObject("PRSP_MAT")) == NULL) {
- WndwInputWindowPutStr(
- "No perspective transformation matrix PRSP_MAT!");
- return NULL;
- }
- else if (!IS_MAT_OBJ(PrspMat)) {
- WndwInputWindowPutStr(
- "PRSP_MAT object was modified (not matrix object)");
- return NULL;
- }
-
- switch (GlblViewMode) {
- case VIEW_ORTHOGRAPHIC:
- GEN_COPY(CrntViewMat, ViewMat -> U.Mat, sizeof(MatrixType));
- break;
- case VIEW_PERSPECTIVE:
- MatMultTwo4by4(CrntViewMat, ViewMat -> U.Mat, PrspMat -> U.Mat);
- break;
- }
-
- return &CrntViewMat;
- }
-
- /*****************************************************************************
- * 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)
- {
- #if !defined(__MSDOS__) && !defined(DJGCC)
- GGClearViewArea();
- #endif /* !__MSDOS__ && !DJGCC */
-
- if (ActiveObjList != NULL)
- ViewGeomObject(ActiveObjList); /* And display it... */
-
- #if !defined(__MSDOS__) && !defined(DJGCC)
- GGGraphicFlush();
- #endif /* !__MSDOS__ && !DJGCC */
- }
-
- /*****************************************************************************
- * 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;
- ObjectStruct *PObj;
-
- while ((PObj = PObjList -> U.PObjList[Param]) != NULL &&
- Param++ < MAX_OBJ_LIST && !QuitView) {
- ViewGeomObject(PObj);
- }
- }
-
- /*****************************************************************************
- * Routine to fetch the internal parameter from the INTERNAL object. *
- *****************************************************************************/
- static int GetInternal(void)
- {
- int Internal;
- ObjectStruct *PObj = GetObject("INTERNAL");
-
- if (PObj == NULL || !IS_NUM_OBJ(PObj)) {
- WndwInputWindowPutStr("No numeric object name INTERNAL is defined");
- 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 as computed by ComputeCrntViewMat. *
- *****************************************************************************/
- void ViewGeomObject(ObjectStruct *PObj)
- {
- int Color, IsPolyline,
- DrawCtlPtColor = GetDrawCtlPt(),
- ViewInternal = GetInternal(),
- RealResolution = GetResolution(FALSE);
- CagdPolylineStruct *CagdPl;
- PolygonStruct *Pl;
- MatrixType *CrntMat;
-
- if (!GlblDoGraphics) return;
-
- QuitView = FALSE;
-
- if (IS_OLST_OBJ(PObj)) {
- /* Invoke the display routine on each of its componenets. */
- ViewGeomObjectList(PObj);
- return;
- }
-
- if (!IS_GEOM_OBJ(PObj)) {
- WndwInputWindowPutStr("None displayable object ignored.");
- return;
- }
-
- Color = GetObjectColor(PObj);
-
- if ((CrntMat = ComputeCrntViewMatrix()) == NULL)
- return;
-
- if (IS_POLY_OBJ(PObj)) {
- Pl = PObj -> U.Pl.P;
-
- IsPolyline = IS_POLYLINE_OBJ(PObj);
-
- if (!IsPolyline && SupportClosedObject)
- ClosedObject = TRUE;
-
- while (Pl && !QuitView) {
- ViewPolygon(Pl, Color, IsPolyline, *CrntMat, ViewInternal);
- Pl = Pl -> Pnext;
- TestQuitView();/* if break display in the middle - Set QuitView. */
- }
-
- ClosedObject = FALSE;
- }
- else if (IS_CRV_OBJ(PObj)) {
- if (!GlblDrawSolid) {
- ComputeCurveIsoLines(PObj);
-
- if (RealResolution > 0)
- ViewCagdPolyline(PObj -> U.Crv.PLPolys, Color, *CrntMat);
- if (DrawCtlPtColor)
- ViewCagdPolyline(PObj -> U.Crv.CtlPoly, DrawCtlPtColor,
- *CrntMat);
- }
- }
- else if (IS_SRF_OBJ(PObj)) {
- if (GlblDrawSolid) {
- ComputeSurfacePolygons(PObj);
- SetObjectColor(PObj -> U.Srf.Polygons, GetObjectColor(PObj));
-
- ViewGeomObject(PObj -> U.Srf.Polygons);
- }
- else {
- ComputeSurfaceIsoLines(PObj);
-
- if (RealResolution > 0) {
- CagdPl = PObj -> U.Srf.PLPolys;
- while (CagdPl && !QuitView) {
- ViewCagdPolyline(CagdPl, Color, *CrntMat);
- CagdPl = CagdPl -> Pnext;
- TestQuitView();/* Break display in middle - Set QuitView. */
- }
- }
-
- if (DrawCtlPtColor) {
- CagdPl = PObj -> U.Srf.CtlMesh;
- while (CagdPl && !QuitView) {
- ViewCagdPolyline(CagdPl, DrawCtlPtColor, *CrntMat);
- CagdPl = CagdPl -> Pnext;
- TestQuitView();
- }
- }
- }
- }
- }
-
- /*****************************************************************************
- * Routine to display one polyline on the view window using the matrix Mat *
- * as a transformation matrix. *
- *****************************************************************************/
- static void ViewCagdPolyline(CagdPolylineStruct *Pl, int Color,
- MatrixType Mat)
- {
- int i, j;
- PointType P, TempP;
- CagdPtStruct
- *Points = Pl -> Polyline;
-
- /* Since we can not guarantee that CagdRType == RealType: */
- for (i = 0; i < 3; i++) TempP[i] = Points[0].Pt[i];
- MatMultVecby4by4(P, TempP, Mat); /* Transform the first point. */
- DepthCueMoveTo(P);
-
- GGMySetColor(Color);
-
- for (i = 1; i < Pl -> Length; i++) {
- for (j = 0; j < 3; j++) TempP[j] = Points[i].Pt[j];
- MatMultVecby4by4(P, TempP, Mat);
- DepthCueDrawTo(P);
- };
- }
-
- /*****************************************************************************
- * Routine to test if quit display event - occured - *
- * Right button was clicked on mouse. *
- *****************************************************************************/
- static void TestQuitView(void)
- {
- QuitView = GGIsAbortKeyPressed();
- }
-
- /*****************************************************************************
- * 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 IsPolyline,
- MatrixType Mat, int ViewInternal)
- {
- int NumOfPoints, DontDraw,
- ShowNormals = ViewNormals && !IsPolyline;
- PointType P, CenterP;
- VertexStruct *V, *VStart;
-
- V = VStart = Pl -> V;
- if (V == NULL) FatalError("ViewPolygon: Empty polygon to view\n");
-
- GGMySetColor(Color);
-
- #ifdef __GL__ /* Only on GL library systems. */
- if (GlblDrawSolid && !IsPolyline) {
- DrawPolygonSolid(Pl, Mat);
- return;
- }
- #endif
-
- MatMultVecby4by4(P, V -> Pt, Mat); /* Transform the first point. */
- DepthCueMoveTo(P);
- DontDraw = IS_INTERNAL_EDGE(V) && !ViewInternal; /* Draw next edge? */
-
- 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)
- DepthCueMoveTo(P);
- else
- DepthCueDrawTo(P);
-
- 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. */
- DepthCueMoveTo(P);
- PT_COPY(P, Pl -> Plane);
- PT_SCALE(P, NormalsSize);
- PT_ADD(CenterP, CenterP, P);
- MatMultVecby4by4(P, CenterP, Mat); /* Transform the second point. */
- GGMySetColor(NormalsColor);
- DepthCueDrawTo(P);
- }
- }
-
- /*****************************************************************************
- * 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;
- }
-
- /*****************************************************************************
- * Routine to set the closed objects default. *
- *****************************************************************************/
- void ViewSetClosed(RealType *Closed)
- {
- SupportClosedObject = !APX_EQ(*Closed, 0.0);
- }
-
- /*****************************************************************************
- * Routine to mave to 3D point given as Coord[3], using Mat transform. *
- *****************************************************************************/
- static void DepthCueMoveTo(RealType Coord[3])
- {
- GEN_COPY(LastCoord, Coord, 3 * sizeof(RealType)); /* Set crnt point. */
- }
-
- /*****************************************************************************
- * Routine to draw to 3D point given as Coord[3], using Mat transform, from *
- * the last point we moved to. *
- *****************************************************************************/
- static void DepthCueDrawTo(RealType NewCoord[3])
- {
- RealType MiddleCoord[3], t;
-
- if (ClosedObject && NewCoord[2] < LastCoord[2]) {
- GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType));
- return;
- }
-
- /* Implementation of simple depth cue - if line is >Z or <Z ... */
- if (LastCoord[2] <= 0.0 && NewCoord[2] <= 0.0) { /* Draw the <Z part: */
-
- if (GlblDepthCue) GGMySetLineStyle(DOTTED_LINE);
-
- 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) {
- if (GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
-
- 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;
-
- if (GlblDepthCue) GGMySetLineStyle(SOLID_LINE);
-
- 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! */
- }
-
- if (GlblDepthCue) GGMySetLineStyle(DOTTED_LINE);/* 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(RealType)); /* Set crnt point. */
- }
-
- #ifdef __GL__
-
- /****************************************************************************
- * Routine to draw a polygon full. *
- ****************************************************************************/
- static void DrawPolygonSolid(PolygonStruct *PPolygon, MatrixType Mat)
- {
- int i, l = 0;
- float Normal[3], Length;
- double MappedVertex[3];
- RealType V1R[3], V2R[3], V3R[3];
- VertexStruct *PList = PPolygon -> V;
-
- GGMyDrawPolygonSolid(NULL, NULL, TRUE);
-
- do {
- MatMultVecby4by4(V1R, PList -> Pt, Mat);
- for (i = 0; i < 3; i++) MappedVertex[i] = V1R[i];
-
- /* Each vertex has different normal - specify them. */
- MatMultVecby4by4(V1R, PList -> Pt, Mat);
- for (i = 0; i < 3; i++)
- V2R[i] = PList -> Pt[i] + PList -> Normal[i];
- MatMultVecby4by4(V2R, V2R, Mat);
- for (i = 0; i < 3; i++) Normal[i] = V2R[i] - V1R[i];
- Length = sqrt(SQR(Normal[0]) + SQR(Normal[1]) + SQR(Normal[2]));
- for (i = 0; i < 3; i++) Normal[i] /= -Length;
-
- GGMyDrawPolygonSolid(MappedVertex, Normal, TRUE);
-
- PList = PList -> Pnext;
-
- if (l++ >= 255)
- FatalError("GL: polygon too complex (> 256 vertices).\n");
- }
- while (PList != NULL && PList != PPolygon -> V);
-
- GGMyDrawPolygonSolid(NULL, NULL, FALSE);
- }
-
- #endif /* __GL__ */
-
-