home *** CD-ROM | disk | FTP | other *** search
- /* engine.c */
-
- /* written by : Jason R. Wilson 2/21/93 */
-
- /* provides user interface with access to radiosity engine */
-
- #import <math.h>
- #include <stdio.h>
- #include "datastruct.h"
- #include "vector-matrix.h"
- #include "clip.h"
- #include "misc.h"
- #include "objIO.h"
- #include "render.h"
- #include "hemicube.h"
- #include "wireframe.h"
- #include "mesh.h"
- #include "NeXtInterface.h"
-
- #define PI 3.141592654
- #define GaussTol 0.0001 /* gives a .01% tolerence for Gauss-Siedel */
- double **FFMatrix; /* don't forget to offset by 1!!! */
- double **Zbuffer;
- Color **ScreenMap;
- Matrix Composition;
- Point VRP;
- Vector VPN,Up,u,v,n;
- Window ViewWindow;
- double Eye;
- double dotprod;
- Vector upp;
- int NumPolys;
- int NumVerts;
- int adaptive;
- double MoveFactor = 0.1; /* the amount to add on to vectors when moving */
- double TurnFactor = 1.0; /* the angle of the turn */
-
- double MaxIntensity;
-
-
-
- /*----------------------------------------------------------------------*/
- void ReadScene (char *SceneFileName)
- {
-
- /* reads in a .scene file */
-
- FILE *fp; /* This is the file pointer for the scene file */
- char ObjectFileName[256];
- unsigned int TransformType;
- Matrix Copy,New,NewIn,CopyIn;
- double scaleX,scaleY,scaleZ;
- double transX,transY,transZ;
- ObjectCell *Object;
- int NumObjects;
- int loop;
- double c,s;
- int rotationType;
- double rotationAngle;
- double adaptivetol;
- int shouldadapt;
-
-
- ObjectHead = NULL;
-
- printf ("Welcome to NeXtRad!\n");
- printf ("Please enter the name of the scene that you wish to view:\n");
- scanf ("%s",SceneFileName);
- fp = fopen(SceneFileName,"r"); /* open data file */
-
- fscanf (fp,"%lf %lf %lf",&VRP.x,&VRP.y,&VRP.z); /* read in VRP */
- fscanf (fp,"%lf %lf %lf",&VPN.dx,&VPN.dy,&VPN.dz); /* read in VPN */
- fscanf (fp,"%lf %lf %lf",&Up.dx,&Up.dy,&Up.dz); /* read in up vector */
- fscanf (fp,"%lf %lf %lf %lf",&ViewWindow.Wl,&ViewWindow.Wr,
- &ViewWindow.Wb,&ViewWindow.Wt); /* Viewwindow */
- fscanf (fp,"%lf",&Eye); /* eye */
- fscanf (fp,"%d",&adaptive); /* number of times to adaptively subdivide the mesh */
- fscanf (fp,"%lf",&adaptivetol); /* read in the tolerence for adaptive subdivision */
-
- initAdaptiveTol (adaptivetol); /* init. value in the mesh package */
-
- /* Compute u,v,n */
-
- n = Normalize (VPN);
- dotprod = Dotprod (Up,n);
- upp.dx = Up.dx - dotprod*n.dx;
- upp.dy = Up.dy - dotprod*n.dy;
- upp.dz = Up.dz - dotprod*n.dz;
- v = Normalize (upp);
- u = Cross (n,v);
-
- ProduceTransform (VRP,u,v,n,Eye,&Composition);
-
- fscanf (fp,"%d",&NumObjects); /* get the number of objects */
-
-
- for (loop = 0;loop < NumObjects;loop++)
- {
- fscanf (fp,"%s",ObjectFileName); /* get object file name */
- Object = (ObjectCell *)(malloc(sizeof(ObjectCell)));
- InitObjectCell (Object);
- fscanf (fp,"%d",&shouldadapt); /* should this object be adaptively subdivided */
- if (shouldadapt == 0)
- Object->ShouldAdapt = false;
- else
- Object->ShouldAdapt = true;
- ReadInObject (Object,ObjectFileName);
- createIdentity (4,Object->Transform.mat);
- createIdentity (4,Object->InverseTransform.mat);
-
- /* read in subdivision factor */
- fscanf (fp,"%d",&Object->SubFactor);
-
- fscanf (fp,"%u",&TransformType); /* what kind of transform */
-
- while (!(TransformType == 0))
- {
- createIdentity (4,New.mat);
- createIdentity (4,NewIn.mat);
-
- switch (TransformType) {
- case 1: /* rotation */
- fscanf (fp,"%d %lf",&rotationType,&rotationAngle);
- c = cos(rotationAngle*PI/180.0);
- s = sin(rotationAngle*PI/180.0);
- switch (rotationType) {
- case 1: /* rotation about x-axis */
- New.mat[5] = c;
- New.mat[6] = s;
- New.mat[9] = (-1.0)*s;
- New.mat[10] = c;
- Transpose (&New,&NewIn);
- break;
- case 2: /* rotation about y-axis */
- New.mat[0] = c;
- New.mat[2] = (-1.0)*s;
- New.mat[8] = s;
- New.mat[10] = c;
- Transpose (&New,&NewIn);
- break;
- case 3: /* rotation about z-axis */
- New.mat[0] = c;
- New.mat[1] = s;
- New.mat[4] = (-1.0)*s;
- New.mat[5] = c;
- Transpose (&New,&NewIn);
- break; }
- break;
- case 2: /* scale */
- fscanf (fp,"%lf %lf %lf",&scaleX,&scaleY,&scaleZ);
- New.mat[0] = scaleX;
- New.mat[5] = scaleY;
- New.mat[10] = scaleZ;
- NewIn.mat[0] = 1.0/scaleX;
- NewIn.mat[5] = 1.0/scaleY;
- NewIn.mat[10] = 1.0/scaleZ;
- break;
- case 3: /* translate */
- fscanf (fp,"%lf %lf %lf",&transX,&transY,&transZ);
- New.mat[12] = transX;
- New.mat[13] = transY;
- New.mat[14] = transZ;
- NewIn.mat[12] = (-1.0)*transX;
- NewIn.mat[13] = (-1.0)*transY;
- NewIn.mat[14] = (-1.0)*transZ;
- break;
- }
-
- matrixCopy (Object->Transform.mat,Copy.mat);
- matrixMultiply (4,Copy.mat,New.mat,Object->Transform.mat);
-
- matrixCopy (Object->InverseTransform.mat,CopyIn.mat);
- matrixMultiply (4,NewIn.mat,CopyIn.mat,Object->InverseTransform.mat);
-
- fscanf (fp,"%u",&TransformType); /* what kind of transform */
- }
-
-
- /* insert object into object list */
-
-
- if (ObjectHead == NULL)
- {
- ObjectHead = Object;
- Object->Next = NULL;
- }
- else
- {
- Object->Next = ObjectHead;
- ObjectHead = Object;
- }
-
- }
-
- close (fp);
-
- }
-
-
- /***********************************************************************/
-
- void SetUpVectors (ObjectCell *ObjectHead,Color *BVec,Color *EVec,
- Color *RVec,int NumPolys)
-
- {
- ObjectCell *Object;
- PolygonCell *Poly;
- int loop;
-
-
- /* set up the initial vectors */
-
- Object = ObjectHead;
- Poly = Object->PolygonHead;
-
- for (loop = 0;loop < NumPolys;loop++)
- {
- EVec[loop].r = Poly->E.r;
- EVec[loop].g = Poly->E.g;
- EVec[loop].b = Poly->E.b;
-
- RVec[loop].r = Poly->R.r;
- RVec[loop].g = Poly->R.g;
- RVec[loop].b = Poly->R.b;
-
- BVec[loop].r = EVec[loop].r;
- BVec[loop].g = EVec[loop].g;
- BVec[loop].b = EVec[loop].b;
-
- if ((Poly->Next == NULL) && (!(Object->Next == NULL)))
- {
- Object = Object->Next;
- Poly = Object->PolygonHead;
- }
- else
- Poly = Poly->Next;
- }
-
- }
-
-
- /*----------------------------------------------------------------------*/
-
-
- void ComputeRadiosityIntensities (ObjectCell *ObjectHead,int NumPolys)
-
- /* Computes the intensities at each vertex using radiosity */
-
- {
- Color BVec[NumPolys];
- Color EVec[NumPolys];
- Color RVec[NumPolys];
- Color Old[NumPolys]; /* used to measure change */
- ObjectCell *Object;
- PolygonCell *Poly;
- int loop,loop2,loop3;
- int count;
- VertexCell *CurrentVert;
- PolygonListCell *CurrentListPoly;
- Boolean GoOn; /* should Gauss-Siedel continue? */
-
- /* get memory for form-factor matrix */
-
- FFMatrix = (double **)(malloc(NumPolys*sizeof(double *)));
- for (loop = 0;loop < NumPolys;loop++)
- FFMatrix[loop] = (double *)(malloc(NumPolys*sizeof(double)));
-
-
- /* init. the form-factor matrix */
- for (loop = 0;loop < NumPolys;loop++)
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- FFMatrix[loop][loop2] = 0.0;
-
- SetUpVectors (ObjectHead,BVec,EVec,RVec,NumPolys); /* init. the vectors */
-
- /* compute the form-factors */
-
- Object = ObjectHead;
- Poly = ObjectHead->PolygonHead;
-
-
- for (loop = 0;loop < NumPolys;loop++)
- {
- printf ("projecting onto patch %d\n",loop + 1);
-
- ProjectPatch(Poly,FFMatrix[loop]); /* compute the row of form-factors for patch */
-
- /* advance the poly pointer */
-
- if ((Poly->Next == NULL) && (!(Object->Next == NULL)))
- {
- Object = Object->Next;
- Poly = Object->PolygonHead;
- }
- else
- Poly = Poly->Next;
- }
-
- /* let's see the results ! */
-
- /*
- for (loop = 0;loop < NumPolys;loop++)
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- printf ("the %d,%d form-factor is %lf\n",loop,loop2,
- FFMatrix[loop][loop2]);
- */
-
- /* iteratively solve for the radiosities (to given tol.) */
-
- printf ("solving matrix ... \n");
- loop3 = 0; /* count the number of iterations required */
- GoOn = true;
- while (GoOn == true)
- {
- GoOn = false; /* assume done */
- loop3++; /* another iteration */
- for (loop = 0;loop < NumPolys;loop++)
- {
- Old[loop].r = BVec[loop].r;
- Old[loop].g = BVec[loop].g;
- Old[loop].b = BVec[loop].b;
- }
- for (loop = 0;loop < NumPolys;loop++)
- {
- BVec[loop].r = EVec[loop].r;
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- if (!(loop2 == loop))
- BVec[loop].r += RVec[loop].r*
- BVec[loop2].r*FFMatrix[loop][loop2];
- BVec[loop].g = EVec[loop].g;
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- if (!(loop2 == loop))
- {
- BVec[loop].g += RVec[loop].g*
- BVec[loop2].g*FFMatrix[loop][loop2];
- }
- BVec[loop].b = EVec[loop].b;
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- if (!(loop2 == loop))
- {
- BVec[loop].b += RVec[loop].b*
- BVec[loop2].b*FFMatrix[loop][loop2];
- }
- }
- /* next, test to see if another iteration is required */
- for (loop = 0;loop < NumPolys;loop++)
- {
- if ((((Old[loop].r - BVec[loop].r)/Old[loop].r) > GaussTol) ||
- (((Old[loop].r - BVec[loop].r)/BVec[loop].r) < (-1.0*GaussTol)))
- GoOn = true;
- if ((((Old[loop].g - BVec[loop].g)/Old[loop].g) > GaussTol) ||
- (((Old[loop].g - BVec[loop].g)/BVec[loop].g) < (-1.0*GaussTol)))
- GoOn = true;
- if ((((Old[loop].b - BVec[loop].b)/Old[loop].b) > GaussTol) ||
- (((Old[loop].b - BVec[loop].b)/BVec[loop].b) < (-1.0*GaussTol)))
- GoOn = true;
- }
-
- }
-
- printf ("It took %d iterations\n",loop3);
-
- Object = ObjectHead;
- Poly = ObjectHead->PolygonHead;
-
- for (loop = 0;loop < NumPolys;loop++)
- {
-
- Poly->B.r = BVec[loop].r;
- Poly->B.g = BVec[loop].g;
- Poly->B.b = BVec[loop].b;
-
- /* advance the poly pointer */
-
- if ((Poly->Next == NULL) && (!(Object->Next == NULL)))
- {
- Object = Object->Next;
- Poly = Object->PolygonHead;
- }
- else
- Poly = Poly->Next;
- }
-
- /* move radiosities from patches to vertices */
-
-
- Object = ObjectHead;
-
- while (!(Object == NULL))
- {
- CurrentVert = Object->VertexHead;
- while (!(CurrentVert == NULL))
- {
- CurrentVert->B.r = 0.0;
- CurrentVert->B.g = 0.0;
- CurrentVert->B.b = 0.0;
- count = 0;
- CurrentListPoly = CurrentVert->Polygons;
- while (!(CurrentListPoly == NULL))
- {
- count++;
- CurrentVert->B.r += BVec[(CurrentListPoly->Polygon->ID - 1)].r;
- CurrentVert->B.g += BVec[(CurrentListPoly->Polygon->ID - 1)].g;
- CurrentVert->B.b += BVec[(CurrentListPoly->Polygon->ID - 1)].b;
- CurrentListPoly = CurrentListPoly->Rest;
- }
- CurrentVert->B.r /= (double)count;
- CurrentVert->B.g /= (double)count;
- CurrentVert->B.b /= (double)count;
-
-
- CurrentVert = CurrentVert->Next;
- }
- Object = Object->Next;
- }
-
- /* free memory for form-factor matrix */
-
- for (loop = 0;loop < NumPolys;loop++)
- free (FFMatrix[loop]);
- free (FFMatrix);
-
-
-
- }
-
-
- /***********************************************************************/
-
- void ReadWorld (void)
- /* reads prestored patch and vertex radiosities from a file */
- {
- char filename[256];
- FILE *fp;
- ObjectCell *Object;
- VertexCell *Vertex;
- PolygonCell *Polygon;
-
- printf ("Please enter the name of file that contains the patch and vertex radiosities :\n");
- scanf ("%s",filename);
- printf ("Thank you. Reading ... \n");
- fp = fopen (filename,"r");
- Object = ObjectHead;
- while (!(Object == NULL))
- {
- Vertex = Object->VertexHead;
- while (!(Vertex == NULL))
- {
- fscanf (fp,"%lf %lf %lf",&Vertex->B.r,&Vertex->B.g,&Vertex->B.b);
- Vertex = Vertex->Next;
- }
- Polygon = Object->PolygonHead;
- while (!(Polygon == NULL))
- {
- fscanf (fp,"%lf %lf %lf",&Polygon->B.r,&Polygon->B.g,&Polygon->B.b);
- Polygon = Polygon->Next;
- }
- Object = Object->Next;
- }
- close(fp); /* close the file */
- printf ("Done reading file\n");
-
- }
-
- /***********************************************************************/
-
- void WriteWorld (void)
- /* writes vertex and patch radiosities to a file for storage */
- {
- char filename[256];
- FILE *fp;
- ObjectCell *Object;
- VertexCell *Vertex;
- PolygonCell *Polygon;
-
- printf ("Please enter the name of the output file\n");
- scanf ("%s",filename);
- printf ("Thank you. Writing ... \n");
- fp = fopen (filename,"w");
- Object = ObjectHead;
- while (!(Object == NULL))
- {
- Vertex = Object->VertexHead;
- while (!(Vertex == NULL))
- {
- fprintf (fp,"%lf %lf %lf\n",Vertex->B.r,Vertex->B.g,Vertex->B.b);
- Vertex = Vertex->Next;
- }
- Polygon = Object->PolygonHead;
- while (!(Polygon == NULL))
- {
- fprintf (fp,"%lf %lf %lf\n",Polygon->B.r,Polygon->B.g,Polygon->B.b);
- Polygon = Polygon->Next;
- }
- Object = Object->Next;
- }
- close(fp); /* close the file */
- printf ("Done writing file\n");
-
- }
-
-
- /***********************************************************************/
-
- void InitComp(void)
- /* get initial mesh, radiosities for the initial mesh, and perform initial
- adaptive subdivisions. */
-
- {
- int loop,loop2;
- ObjectCell *Object;
- char answer[256];
-
- Object = ObjectHead;
- while (!(Object == NULL))
- {
- TransformObject (Object);
- IdentifyVertices(Object);
- for (loop = 0;loop < (Object->SubFactor - 1);loop++)
- {
- SubDivide (Object,Object->NoofVertices);
- IdentifyVertices(Object);
- }
- ComputeNormals (Object);
- Object = Object->Next;
- }
-
-
- NumPolys = IdentifyPolys (ObjectHead);
- NumVerts = IdentifyVerts (ObjectHead);
-
- printf ("here is numpolys %d\n",NumPolys);
- printf ("here is numverts %d\n",NumVerts);
-
-
- printf ("About to compute patch radiosities!\n");
- printf ("Would you like to load them from a file : (y or n)\n");
- scanf ("%s",answer);
- if ((answer[0] == 'y') || (answer[0] == 'Y'))
- ReadWorld();
- else
- {
- ComputeRadiosityIntensities (ObjectHead,NumPolys);
- printf ("Patch Radiosities have been computed for this scene!\n");
- printf ("Would you like to write them to a file : (y or n)\n");
- scanf ("%s",answer);
- if ((answer[0] == 'y') || (answer[0] == 'Y'))
- WriteWorld();
- }
-
- for (loop = 0;loop < adaptive;loop++)
- {
- printf ("subdividing...\n");
- Object = ObjectHead;
- while (!(Object == NULL))
- {
- if (Object->ShouldAdapt == true)
- {
- IdentifyVertices(Object);
- SubdivideObjects(Object,Object->NoofVertices,NumPolys);
- }
- Object = Object->Next;
- }
-
- }
-
-
-
- }
- /*----------------------------------------------------------------------*/
-
- void adapt(void)
- /* does an adaptive mesh-generation pass */
-
- {
- ObjectCell *Object;
-
- printf ("adaptively subdividing ...\n");
- Object = ObjectHead;
- while (!(Object == NULL))
- {
- if (Object->ShouldAdapt == true)
- {
- IdentifyVertices(Object);
- SubdivideObjects(Object,Object->NoofVertices,NumPolys);
- }
- Object = Object->Next;
- }
- }
- /*----------------------------------------------------------------------*/
- void renderit(void)
- {
- /* render the scene */
-
- int loop,loop2;
- ObjectCell *Object;
-
- CullBackFaces (ObjectHead,Eye,VRP,n); /* cull back faces */
- TransformView (ObjectHead,Composition); /* compute view coordinates */
-
- MaxIntensity = -1.0; /* init. max intensity */
-
- /* init. Zbuffer and ScreenMap */
- for (loop = 0;loop < winHeight;loop++)
- for (loop2 = 0;loop2 < winWidth;loop2++)
- {
- Zbuffer[loop2][loop] = 1000.0; /* ?!?!? */
- ScreenMap[loop2][loop].r = 0.0;
- ScreenMap[loop2][loop].g = 0.0;
- ScreenMap[loop2][loop].b = 0.0;
- }
-
-
- Object = ObjectHead;
-
- while (!(Object == NULL))
- {
- RenderObject (Object,Zbuffer,ScreenMap,ViewWindow,&MaxIntensity,
- winWidth,winHeight,u,v,n,VRP);
- Object = Object->Next;
- }
-
-
- printf ("writing to ScreenBuf ...\n");
-
- for (loop = 0;loop < winHeight;loop++)
- for (loop2 = 0;loop2 < winWidth;loop2++)
- {
- SetPixel (loop2,loop,((unsigned char)(rint(((
- ScreenMap[loop2][loop].r)/MaxIntensity)*255))),
- ((unsigned char)(rint(((
- ScreenMap[loop2][loop].g)/MaxIntensity)*255))),
- ((unsigned char)(rint(((
- ScreenMap[loop2][loop].b)/MaxIntensity)*255))));
- }
- printf ("done\n");
-
- }
-
- /*----------------------------------------------------------------------*/
-
- void WireFrameFull(void)
- /* outputs the full wireframe (including elements) */
- {
- DrawWireFull (ObjectHead);
- }
-
- /*----------------------------------------------------------------------*/
-
- void WireFrame(void)
- /* outputs the coarse wireframe (only patches) */
- {
- DrawWire (ObjectHead);
- }
-
- /*----------------------------------------------------------------------*/
-
- void Faster(void)
- /* change MoveFactor so user moves faster */
- /* change TurnFactor so user turns faster */
- {
- MoveFactor = MoveFactor*1.5; /* add 50% */
- TurnFactor = TurnFactor*1.5; /* ditto */
- }
-
- /*----------------------------------------------------------------------*/
-
- void Slower(void)
- /* change MoveFactor so user moves slower */
- /* change TurnFactor so user turns faster */
- {
- MoveFactor = MoveFactor/1.5;
- TurnFactor = TurnFactor/1.5;
- }
-
- /*----------------------------------------------------------------------*/
- void ChangeView(int dir)
- /* changes the viewpoint for walkthrough */
- {
- Matrix New;
- double c,s;
- Vector temp1,temp2;
- Vector u1,v1,n1;
-
- switch (dir) {
- case 1: {
- VRP.x += MoveFactor*n.dx;
- VRP.y += MoveFactor*n.dy;
- VRP.z += MoveFactor*n.dz;
- break; }
- case 2: {
- VRP.x -= MoveFactor*n.dx;
- VRP.y -= MoveFactor*n.dy;
- VRP.z -= MoveFactor*n.dz;
- break; }
- case 3: {
- createIdentity(4,New.mat);
- c = cos((-1.0)*TurnFactor*PI/180.0);
- s = sin((-1.0)*TurnFactor*PI/180.0);
- New.mat[0] = c;
- New.mat[2] = (-1.0)*s;
- New.mat[8] = s;
- New.mat[10] = c;
- temp1.dx = 0.0;
- temp1.dy = 0.0;
- temp1.dz = 1.0;
- n1.dx = temp1.dx * New.mat[0] + temp1.dy * New.mat[4] + temp1.dz * New.mat[8] + 1.0 * New.mat[12];
- n1.dy = temp1.dx * New.mat[1] + temp1.dy * New.mat[5] + temp1.dz * New.mat[9] + 1.0 * New.mat[13];
- n1.dz = temp1.dx * New.mat[2] + temp1.dy * New.mat[6] + temp1.dz * New.mat[10] + 1.0 * New.mat[14];
- temp1.dx = u.dx*n1.dx + v.dx*n1.dy + n.dx*n1.dz + VRP.x;
- temp1.dy = u.dy*n1.dx + v.dy*n1.dy + n.dy*n1.dz + VRP.y;
- temp1.dz = u.dz*n1.dx + v.dz*n1.dy + n.dz*n1.dz + VRP.z;
- temp2.dx = 1.0;
- temp2.dy = 0.0;
- temp2.dz = 0.0;
- u1.dx = temp2.dx * New.mat[0] + temp2.dy * New.mat[4] + temp2.dz * New.mat[8] + 1.0 * New.mat[12];
- u1.dy = temp2.dx * New.mat[1] + temp2.dy * New.mat[5] + temp2.dz * New.mat[9] + 1.0 * New.mat[13];
- u1.dz = temp2.dx * New.mat[2] + temp2.dy * New.mat[6] + temp2.dz * New.mat[10] + 1.0 * New.mat[14];
- temp2.dx = u.dx*u1.dx + v.dx*u1.dy + n.dx*u1.dz + VRP.x;
- temp2.dy = u.dy*u1.dx + v.dy*u1.dy + n.dy*u1.dz + VRP.y;
- temp2.dz = u.dz*u1.dx + v.dz*u1.dy + n.dz*u1.dz + VRP.z;
- temp1.dx -= VRP.x;
- temp1.dy -= VRP.y;
- temp1.dz -= VRP.z;
- temp2.dx -= VRP.x;
- temp2.dy -= VRP.y;
- temp2.dz -= VRP.z;
- n = Normalize(temp1);
- u = Normalize(temp2);
- break; }
- case 4: {
- createIdentity(4,New.mat);
- c = cos(TurnFactor*PI/180.0);
- s = sin(TurnFactor*PI/180.0);
- New.mat[0] = c;
- New.mat[2] = (-1.0)*s;
- New.mat[8] = s;
- New.mat[10] = c;
- temp1.dx = 0.0;
- temp1.dy = 0.0;
- temp1.dz = 1.0;
- n1.dx = temp1.dx * New.mat[0] + temp1.dy * New.mat[4] + temp1.dz * New.mat[8] + 1.0 * New.mat[12];
- n1.dy = temp1.dx * New.mat[1] + temp1.dy * New.mat[5] + temp1.dz * New.mat[9] + 1.0 * New.mat[13];
- n1.dz = temp1.dx * New.mat[2] + temp1.dy * New.mat[6] + temp1.dz * New.mat[10] + 1.0 * New.mat[14];
- temp1.dx = u.dx*n1.dx + v.dx*n1.dy + n.dx*n1.dz + VRP.x;
- temp1.dy = u.dy*n1.dx + v.dy*n1.dy + n.dy*n1.dz + VRP.y;
- temp1.dz = u.dz*n1.dx + v.dz*n1.dy + n.dz*n1.dz + VRP.z;
- temp2.dx = 1.0;
- temp2.dy = 0.0;
- temp2.dz = 0.0;
- u1.dx = temp2.dx * New.mat[0] + temp2.dy * New.mat[4] + temp2.dz * New.mat[8] + 1.0 * New.mat[12];
- u1.dy = temp2.dx * New.mat[1] + temp2.dy * New.mat[5] + temp2.dz * New.mat[9] + 1.0 * New.mat[13];
- u1.dz = temp2.dx * New.mat[2] + temp2.dy * New.mat[6] + temp2.dz * New.mat[10] + 1.0 * New.mat[14];
- temp2.dx = u.dx*u1.dx + v.dx*u1.dy + n.dx*u1.dz + VRP.x;
- temp2.dy = u.dy*u1.dx + v.dy*u1.dy + n.dy*u1.dz + VRP.y;
- temp2.dz = u.dz*u1.dx + v.dz*u1.dy + n.dz*u1.dz + VRP.z;
- temp1.dx -= VRP.x;
- temp1.dy -= VRP.y;
- temp1.dz -= VRP.z;
- temp2.dx -= VRP.x;
- temp2.dy -= VRP.y;
- temp2.dz -= VRP.z;
- n = Normalize(temp1);
- u = Normalize(temp2);
- break; }
- case 5: {
- createIdentity(4,New.mat);
- c = cos((-1.0)*TurnFactor*PI/180.0);
- s = sin((-1.0)*TurnFactor*PI/180.0);
- New.mat[5] = c;
- New.mat[6] = s;
- New.mat[9] = (-1.0)*s;
- New.mat[10] = c;
- temp1.dx = 0.0;
- temp1.dy = 0.0;
- temp1.dz = 1.0;
- n1.dx = temp1.dx * New.mat[0] + temp1.dy * New.mat[4] + temp1.dz * New.mat[8] + 1.0 * New.mat[12];
- n1.dy = temp1.dx * New.mat[1] + temp1.dy * New.mat[5] + temp1.dz * New.mat[9] + 1.0 * New.mat[13];
- n1.dz = temp1.dx * New.mat[2] + temp1.dy * New.mat[6] + temp1.dz * New.mat[10] + 1.0 * New.mat[14];
- temp1.dx = u.dx*n1.dx + v.dx*n1.dy + n.dx*n1.dz + VRP.x;
- temp1.dy = u.dy*n1.dx + v.dy*n1.dy + n.dy*n1.dz + VRP.y;
- temp1.dz = u.dz*n1.dx + v.dz*n1.dy + n.dz*n1.dz + VRP.z;
- temp2.dx = 0.0;
- temp2.dy = 1.0;
- temp2.dz = 0.0;
- v1.dx = temp2.dx * New.mat[0] + temp2.dy * New.mat[4] + temp2.dz * New.mat[8] + 1.0 * New.mat[12];
- v1.dy = temp2.dx * New.mat[1] + temp2.dy * New.mat[5] + temp2.dz * New.mat[9] + 1.0 * New.mat[13];
- v1.dz = temp2.dx * New.mat[2] + temp2.dy * New.mat[6] + temp2.dz * New.mat[10] + 1.0 * New.mat[14];
- temp2.dx = u.dx*v1.dx + v.dx*v1.dy + n.dx*v1.dz + VRP.x;
- temp2.dy = u.dy*v1.dx + v.dy*v1.dy + n.dy*v1.dz + VRP.y;
- temp2.dz = u.dz*v1.dx + v.dz*v1.dy + n.dz*v1.dz + VRP.z;
- temp1.dx -= VRP.x;
- temp1.dy -= VRP.y;
- temp1.dz -= VRP.z;
- temp2.dx -= VRP.x;
- temp2.dy -= VRP.y;
- temp2.dz -= VRP.z;
- n = temp1;
- v = temp2;
- break; }
- case 6: {
- createIdentity(4,New.mat);
- c = cos(TurnFactor*PI/180.0);
- s = sin(TurnFactor*PI/180.0);
- New.mat[5] = c;
- New.mat[6] = s;
- New.mat[9] = (-1.0)*s;
- New.mat[10] = c;
- temp1.dx = 0.0;
- temp1.dy = 0.0;
- temp1.dz = 1.0;
- n1.dx = temp1.dx * New.mat[0] + temp1.dy * New.mat[4] + temp1.dz * New.mat[8] + 1.0 * New.mat[12];
- n1.dy = temp1.dx * New.mat[1] + temp1.dy * New.mat[5] + temp1.dz * New.mat[9] + 1.0 * New.mat[13];
- n1.dz = temp1.dx * New.mat[2] + temp1.dy * New.mat[6] + temp1.dz * New.mat[10] + 1.0 * New.mat[14];
- temp1.dx = u.dx*n1.dx + v.dx*n1.dy + n.dx*n1.dz + VRP.x;
- temp1.dy = u.dy*n1.dx + v.dy*n1.dy + n.dy*n1.dz + VRP.y;
- temp1.dz = u.dz*n1.dx + v.dz*n1.dy + n.dz*n1.dz + VRP.z;
- temp2.dx = 0.0;
- temp2.dy = 1.0;
- temp2.dz = 0.0;
- v1.dx = temp2.dx * New.mat[0] + temp2.dy * New.mat[4] + temp2.dz * New.mat[8] + 1.0 * New.mat[12];
- v1.dy = temp2.dx * New.mat[1] + temp2.dy * New.mat[5] + temp2.dz * New.mat[9] + 1.0 * New.mat[13];
- v1.dz = temp2.dx * New.mat[2] + temp2.dy * New.mat[6] + temp2.dz * New.mat[10] + 1.0 * New.mat[14];
- temp2.dx = u.dx*v1.dx + v.dx*v1.dy + n.dx*v1.dz + VRP.x;
- temp2.dy = u.dy*v1.dx + v.dy*v1.dy + n.dy*v1.dz + VRP.y;
- temp2.dz = u.dz*v1.dx + v.dz*v1.dy + n.dz*v1.dz + VRP.z;
- temp1.dx -= VRP.x;
- temp1.dy -= VRP.y;
- temp1.dz -= VRP.z;
- temp2.dx -= VRP.x;
- temp2.dy -= VRP.y;
- temp2.dz -= VRP.z;
- n = temp1;
- v = temp2;
- break; } }
-
- ProduceTransform (VRP,u,v,n,Eye,&Composition);
- CullBackFaces (ObjectHead,Eye,VRP,n);
- TransformView (ObjectHead,Composition);
- }
-
- /*----------------------------------------------------------------------*/
- void engine (char *SceneFileName)
- /* renders the scene from the initial viewpoint */
- {
- int loop;
-
- ReadScene(SceneFileName);
- InitWire (ViewWindow,winWidth,winHeight); /* set up the wire-frame package */
- ComputeDeltas (); /* precompute the delta form factors for the hemicube */
- InitComp();
-
-
- Zbuffer = (double **)(malloc(winWidth*sizeof(double *)));
- for (loop = 0;loop < winWidth;loop++)
- Zbuffer[loop] = (double *)(malloc(winHeight*sizeof(double)));
-
- ScreenMap = (Color **)(malloc(winWidth*sizeof(Color *)));
- for (loop = 0;loop < winWidth;loop++)
- ScreenMap[loop] = (Color *)(malloc(winHeight*sizeof(Color)));
-
- renderit();
-
-
- }
-
-
- /*----------------------------------------------------------------------*/
-
-
-
-
-
-