home *** CD-ROM | disk | FTP | other *** search
- /* mesh.c */
- /* written by : Jason R. Wilson 2/21/93 */
-
- /* provides routines for initial mesh generation and adaptive mesh generation */
-
- #include "datastruct.h"
- #include <stdio.h>
- #include "hemicube.h"
-
- VertexCell ***EdgeMatrix; /* needs to be global */
-
- /* use an edge matrix */
-
- float AdaptiveTol;
-
- void initAdaptiveTol (double tol)
- {
- AdaptiveTol = tol;
- }
-
-
- void SubDivide (ObjectCell *Object,int NumVertices)
- {
-
- /* assume that vertices have been identified with IdentifyVertex */
-
- int loop,loop2;
- PolygonCell *CurrentPoly,*temp;
- VertexListCell *CurrentVertList;
- VertexCell *a,*b,*c,*d;
- VertexCell *OldVertices[4];
- VertexCell *NewVertices[5];
- PolygonCell *NewPolyList;
- PolygonCell *NewPoly;
- PolygonListCell *CurrentPolyList;
- VertexCell *LocalVertices[4];
-
- /* get mem. for edge matrix */
-
- EdgeMatrix = (VertexCell ***)(malloc((NumVertices+1)*sizeof(VertexCell **)));
- for (loop = 0;loop < NumVertices + 1;loop++)
- EdgeMatrix[loop] = (VertexCell **)(malloc((NumVertices+1)*sizeof(VertexCell *)));
-
- /* init. edge matrix pointers to NULL */
-
- for (loop = 0;loop <= NumVertices;loop++)
- for (loop2 = 0;loop2 <= NumVertices;loop2++)
- EdgeMatrix[loop][loop2] = NULL;
-
- NewPolyList = NULL;
-
- /* through each polygon and create 4 new vertices (one for each edge)
- that will be used for the subdivision */
- /* use the edge matrix to prevent redundent vertices and preserve
- topological info. */
-
- CurrentPoly = Object->PolygonHead;
-
- while (!(CurrentPoly == NULL))
- {
- /* init. d, the new center point of the polygon */
-
- d = (VertexCell *)(malloc(sizeof(VertexCell)));
- InitVertexCell (d);
- d->WorldPosition.x = 0.0;
- d->WorldPosition.y = 0.0;
- d->WorldPosition.z = 0.0;
-
-
- CurrentVertList = CurrentPoly->Vertices;
- for (loop = 0;loop < 4;loop++)
- {
- /* a and b are pointers the the two vertices currently being cons. */
- a = CurrentVertList->Vertex;
- if (loop == 3)
- b = CurrentPoly->Vertices->Vertex;
- else
- b = CurrentVertList->Rest->Vertex;
-
- /* update old vertices array */
-
- OldVertices[loop] = a;
-
- /* update d, the center point */
-
- d->WorldPosition.x += a->WorldPosition.x;
- d->WorldPosition.y += a->WorldPosition.y;
- d->WorldPosition.z += a->WorldPosition.z;
-
-
- if (EdgeMatrix[a->Number][b->Number] == NULL)
- {
- /* need to create new vertex, namely c */
- c = (VertexCell *)(malloc(sizeof(VertexCell)));
- InitVertexCell (c);
- /* update edge matrix */
- EdgeMatrix[a->Number][b->Number] = c;
- EdgeMatrix[b->Number][a->Number] = c;
- /* find position of c by averaging */
- c->WorldPosition.x = (a->WorldPosition.x + b->WorldPosition.x)/2.0;
- c->WorldPosition.y = (a->WorldPosition.y + b->WorldPosition.y)/2.0;
- c->WorldPosition.z = (a->WorldPosition.z + b->WorldPosition.z)/2.0;
- /* insert c into object vertex list */
- c->Next = Object->VertexHead;
- Object->VertexHead = c;
- }
- else
- c = EdgeMatrix[a->Number][b->Number];
-
- NewVertices[loop] = c;
-
- CurrentVertList=CurrentVertList->Rest;
- }
-
- /* average them */
- d->WorldPosition.x /= 4.0;
- d->WorldPosition.y /= 4.0;
- d->WorldPosition.z /= 4.0;
-
- /* insert d into object vertex list */
- d->Next = Object->VertexHead;
- Object->VertexHead = d;
-
-
- /* insert d into newvertex list */
- NewVertices[4] = d;
-
- /* Next remove CurrentPoly from all of the old vertices */
-
- for (loop = 0;loop < 4;loop++)
- {
- CurrentPolyList = OldVertices[loop]->Polygons;
- /* base case */
- if (CurrentPolyList->Polygon == CurrentPoly)
- {
- OldVertices[loop]->Polygons = OldVertices[loop]->Polygons->Rest;
- }
- else
- {
- while (!(CurrentPolyList->Rest->Polygon == CurrentPoly))
- CurrentPolyList = CurrentPolyList->Rest;
- CurrentPolyList->Rest = CurrentPolyList->Rest->Rest;
- }
- }
-
- /* now, create new polygons and add them to the beginning of
- the new polygons list */
-
- for (loop = 0;loop < 4;loop++)
- {
- LocalVertices[0] = OldVertices[loop];
- LocalVertices[1] = NewVertices[loop];
- LocalVertices[2] = NewVertices[4];
- if (!(loop == 0))
- LocalVertices[3] = NewVertices[loop-1];
- else
- LocalVertices[3] = NewVertices[3];
-
- /* create new poly and make it point to all of the vertices */
-
- NewPoly = (PolygonCell *)(malloc(sizeof(PolygonCell)));
- InitPolygonCell (NewPoly);
- NewPoly->Textured = CurrentPoly->Textured;
- NewPoly->R.r = CurrentPoly->R.r;
- NewPoly->R.g = CurrentPoly->R.g;
- NewPoly->R.b = CurrentPoly->R.b;
- NewPoly->E.r = CurrentPoly->E.r;
- NewPoly->E.g = CurrentPoly->E.g;
- NewPoly->E.b = CurrentPoly->E.b;
-
-
- for (loop2 = 3;loop2 > -1 ;loop2--) /* reverse order to preserve order */
- {
- CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
- InitVertexListCell (CurrentVertList);
- CurrentVertList->Vertex = LocalVertices[loop2];
- CurrentVertList->Rest = NewPoly->Vertices;
- NewPoly->Vertices = CurrentVertList;
- }
-
-
- /* go through and make all of the vertices point to the newpoly */
-
- for (loop2 = 0;loop2 < 4;loop2++)
- {
- CurrentPolyList =(PolygonListCell *)(malloc(sizeof(PolygonListCell)));
- InitPolygonListCell (CurrentPolyList);
- CurrentPolyList->Polygon = NewPoly;
- CurrentPolyList->Rest = LocalVertices[loop2]->Polygons;
- LocalVertices[loop2]->Polygons = CurrentPolyList;
- }
-
- /* insert the new polygon into NewPolyList */
-
- NewPoly->Next = NewPolyList;
- NewPolyList = NewPoly;
-
- }
- temp = CurrentPoly;
- CurrentPoly = CurrentPoly->Next; /* process the next polygon */
- free (temp); /* free up storage for old polygon */
- }
- Object->PolygonHead = NewPolyList; /* replace the old poly
- list with the new one */
-
- /* free memory of EdgeMatrix */
-
- for (loop = 0;loop < NumVertices + 1;loop++)
- free (EdgeMatrix[loop]);
- free (EdgeMatrix);
-
- }
-
-
- /*----------------------------------------------------------------------*/
-
-
- CreateNewElements (ObjectCell *Object,PolygonCell *CurrentPoly)
- /* recursively subdivide polygons with high gradients */
-
- {
-
- PolygonCell *NewPoly;
- VertexCell *OldVertices[4];
- VertexCell *NewVertices[5];
- VertexCell *LocalVertices[4];
- VertexCell *a,*b,*c,*d;
- int loop,loop2;
- PolygonListCell *CurrentPolyList;
- VertexListCell *CurrentVertList;
-
-
- printf ("subdivision necessary \n");
- /* subdivision necessary, create 4 new polygons, and 5 new vertices */
-
- /*******************************************************************/
-
- /* init. d, the new center point of the polygon */
-
- d = (VertexCell *)(malloc(sizeof(VertexCell)));
- InitVertexCell (d);
- d->WorldPosition.x = 0.0;
- d->WorldPosition.y = 0.0;
- d->WorldPosition.z = 0.0;
-
- CurrentVertList = CurrentPoly->Vertices;
- for (loop = 0;loop < 4;loop++)
- {
- /* a and b are pointers the the two vertices currently being considered. */
-
- a = CurrentVertList->Vertex;
- if (loop == 3)
- b = CurrentPoly->Vertices->Vertex;
- else
- b = CurrentVertList->Rest->Vertex;
-
- /* update old vertices array */
-
- OldVertices[loop] = a;
-
- /* update d, the center point */
-
- d->WorldPosition.x += a->WorldPosition.x;
- d->WorldPosition.y += a->WorldPosition.y;
- d->WorldPosition.z += a->WorldPosition.z;
-
- if (EdgeMatrix[a->Number][b->Number] == NULL)
- {
- /* need to create new vertex, namely c */
- c = (VertexCell *)(malloc(sizeof(VertexCell)));
- InitVertexCell (c);
- /* update edge matrix */
- EdgeMatrix[a->Number][b->Number] = c;
- EdgeMatrix[b->Number][a->Number] = c;
- /* find position of c by averaging */
- c->WorldPosition.x = (a->WorldPosition.x + b->WorldPosition.x)/2.0;
- c->WorldPosition.y = (a->WorldPosition.y + b->WorldPosition.y)/2.0;
- c->WorldPosition.z = (a->WorldPosition.z + b->WorldPosition.z)/2.0;
- /* insert c into object vertex list */
- c->Next = Object->VertexHead;
- Object->VertexHead = c;
- }
- else
- c = EdgeMatrix[a->Number][b->Number];
-
- NewVertices[loop] = c;
-
- CurrentVertList=CurrentVertList->Rest;
- }
-
- /* average them */
- d->WorldPosition.x /= 4.0;
- d->WorldPosition.y /= 4.0;
- d->WorldPosition.z /= 4.0;
-
- /* insert d into object vertex list */
- d->Next = Object->VertexHead;
- Object->VertexHead = d;
-
- /* insert d into newvertex list */
- NewVertices[4] = d;
-
-
- /******************************************************************/
- /* Next remove CurrentPoly from all of the old vertices */
-
- for (loop = 0;loop < 4;loop++)
- {
- CurrentPolyList = OldVertices[loop]->Polygons;
- /* base case */
- if (CurrentPolyList->Polygon == CurrentPoly)
- {
- OldVertices[loop]->Polygons = OldVertices[loop]->Polygons->Rest;
- }
- else
- {
- while (!(CurrentPolyList->Rest->Polygon == CurrentPoly))
- CurrentPolyList = CurrentPolyList->Rest;
- CurrentPolyList->Rest = CurrentPolyList->Rest->Rest;
- }
- }
-
- /********************************************************************/
-
- /* now, create new polygons and add them to the beginning of
- the new polygons list */
-
- for (loop = 0;loop < 4;loop++)
- {
- LocalVertices[0] = OldVertices[loop];
- LocalVertices[1] = NewVertices[loop];
- LocalVertices[2] = NewVertices[4];
- if (!(loop == 0))
- LocalVertices[3] = NewVertices[loop-1];
- else
- LocalVertices[3] = NewVertices[3];
-
- /* create new poly and make it point to all of the vertices */
-
- NewPoly = (PolygonCell *)(malloc(sizeof(PolygonCell)));
- InitPolygonCell (NewPoly);
- NewPoly->Textured = CurrentPoly->Textured;
- NewPoly->R.r = CurrentPoly->R.r;
- NewPoly->R.g = CurrentPoly->R.g;
- NewPoly->R.b = CurrentPoly->R.b;
- NewPoly->E.r = CurrentPoly->E.r;
- NewPoly->E.g = CurrentPoly->E.g;
- NewPoly->E.b = CurrentPoly->E.b;
- NewPoly->Normal = CurrentPoly->Normal;
-
- for (loop2 = 3;loop2 > -1 ;loop2--) /* reverse order to preserve order */
- {
- CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
- InitVertexListCell (CurrentVertList);
- CurrentVertList->Vertex = LocalVertices[loop2];
- CurrentVertList->Rest = NewPoly->Vertices;
- NewPoly->Vertices = CurrentVertList;
- }
-
-
- /* go through and make all of the vertices point to the newpoly */
-
- for (loop2 = 0;loop2 < 4;loop2++)
- {
- CurrentPolyList =(PolygonListCell *)(malloc(sizeof(PolygonListCell)));
- InitPolygonListCell (CurrentPolyList);
- CurrentPolyList->Polygon = NewPoly;
- CurrentPolyList->Rest = LocalVertices[loop2]->Polygons;
- LocalVertices[loop2]->Polygons = CurrentPolyList;
- }
-
- /* insert the new polygon into NewPolyList */
-
- CurrentPoly->Subs[loop] = NewPoly;
-
- }
- }
-
- /************************************************************/
-
- FixTVertices (PolygonCell *CurrentPoly)
- {
- VertexListCell *traverse,*CurrentVertList;
- PolygonListCell *CurrentPolyList;
- VertexCell *a,*b;
-
- if (!(CurrentPoly->Subs[0] == NULL))
- {
- FixTVertices (CurrentPoly->Subs[0]);
- FixTVertices (CurrentPoly->Subs[1]);
- FixTVertices (CurrentPoly->Subs[2]);
- FixTVertices (CurrentPoly->Subs[3]);
- }
- else
- {
- traverse = CurrentPoly->Vertices;
- while (!(traverse == NULL))
- {
- a = traverse->Vertex;
- if (traverse->Rest == NULL)
- b = CurrentPoly->Vertices->Vertex;
- else
- b = traverse->Rest->Vertex;
- if (EdgeMatrix[a->Number][b->Number] == NULL)
- traverse = traverse->Rest;
- else
- {
- CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
- InitVertexListCell (CurrentVertList);
- CurrentVertList->Vertex = EdgeMatrix[a->Number][b->Number];
- CurrentPolyList = (PolygonListCell *)(malloc(sizeof(PolygonListCell)));
- InitPolygonListCell (CurrentPolyList);
- CurrentPolyList->Polygon = CurrentPoly;
- CurrentPolyList->Rest = CurrentVertList->Vertex->Polygons;
- CurrentVertList->Vertex->Polygons = CurrentPolyList;
- CurrentVertList->Rest = traverse->Rest;
- traverse->Rest = CurrentVertList;
- traverse = CurrentVertList->Rest;
- }
- }
- }
- }
-
- /***********************************************************************/
-
- FindSmallest (ObjectCell *Object,PolygonCell *Poly,int NumPolys)
- {
- Color total; /* used to compute average */
- Boolean MustDivide;
- int count;
- VertexListCell *traverse;
- double *row;
- int loop,loop2;
- PolygonCell *Poly2;
- ObjectCell *Object2;
-
-
- /* make space for row */
-
- row = (double *)(malloc(sizeof(double)*NumPolys));
-
-
- if (Poly->Subs[0] == NULL)
- {
- /******************************************/
- /* go through vertex intensities grouped */
- /* by pnolys... */
- /******************************************/
-
- traverse = Poly->Vertices;
- total.r = 0.0;
- total.g = 0.0;
- total.b = 0.0;
- count = 0;
- while (!(traverse == NULL))
- {
- count++;
- total.r += traverse->Vertex->B.r;
- total.g += traverse->Vertex->B.g;
- total.b += traverse->Vertex->B.b;
- traverse = traverse->Rest;
- }
- total.r = total.r/(double)count;
- total.g = total.g/(double)count;
- total.b = total.b/(double)count;
- /* test for wide variances from average */
- MustDivide = false;
- if (count == 4)
- {
- traverse = Poly->Vertices;
- while (!(traverse == NULL))
- {
- if ((((traverse->Vertex->B.r - total.r)/total.r) > AdaptiveTol) ||
- (((traverse->Vertex->B.r - total.r)/total.r) < -1.0*AdaptiveTol))
- MustDivide = true;
- traverse = traverse->Rest;
- }
- traverse = Poly->Vertices;
- while (!(traverse == NULL))
- {
- if ((((traverse->Vertex->B.g - total.g)/total.g) > AdaptiveTol) ||
- (((traverse->Vertex->B.g - total.g)/total.g) < -1.0*AdaptiveTol))
- MustDivide = true;
- traverse = traverse->Rest;
- }
- traverse = Poly->Vertices;
- while (!(traverse == NULL))
- {
- if ((((traverse->Vertex->B.b - total.b)/total.b) > AdaptiveTol) ||
- (((traverse->Vertex->B.b - total.b)/total.b) < -1.0*AdaptiveTol))
- MustDivide = true;
- traverse = traverse->Rest;
- }
- }
- if (MustDivide == true)
- {
- CreateNewElements (Object,Poly);
- for (loop = 0;loop < 4;loop++)
- {
- for (loop2 = 0;loop2 < NumPolys;loop2++) /* init. row */
- row[loop2] = 0;
- ProjectPatch(Poly->Subs[loop],row);
- Poly->Subs[loop]->B = Poly->Subs[loop]->E;
- Object2 = ObjectHead;
- Poly2 = ObjectHead->PolygonHead;
- for (loop2 = 0;loop2 < NumPolys;loop2++)
- {
- Poly->Subs[loop]->B.r += Poly->Subs[loop]->R.r*row[loop2]*Poly2->B.r;
- Poly->Subs[loop]->B.g += Poly->Subs[loop]->R.g*row[loop2]*Poly2->B.g;
- Poly->Subs[loop]->B.b += Poly->Subs[loop]->R.b*row[loop2]*Poly2->B.b;
- /* advance the poly pointer */
-
- if ((Poly2->Next == NULL) && (!(Object2->Next == NULL)))
- {
- Object2 = Object2->Next;
- Poly2 = Object2->PolygonHead;
- }
- else
- Poly2 = Poly2->Next;
- }
-
- }
- }
- }
- else
- {
- FindSmallest(Object,Poly->Subs[0],NumPolys);
- FindSmallest(Object,Poly->Subs[1],NumPolys);
- FindSmallest(Object,Poly->Subs[2],NumPolys);
- FindSmallest(Object,Poly->Subs[3],NumPolys);
- }
- free (row); /* free up row space */
- }
-
-
- SubdivideObjects (ObjectCell *Object,int NumVertices,int NumPolys)
- /* subdivide polygons with high gradients (4-sided) */
- {
- int loop,loop2;
- PolygonCell *Poly,*CurrentPoly;
- int count;
- VertexCell *CurrentVert;
- PolygonListCell *CurrentListPoly;
-
- /* get memory for adjacency matrix */
- /* are we throwing enough pointers around yet? */
-
- EdgeMatrix = (VertexCell ***)(malloc((NumVertices+1)*sizeof(VertexCell **)));
- for (loop = 0;loop < NumVertices + 1;loop++)
- EdgeMatrix[loop] = (VertexCell **)(malloc((NumVertices+1)*sizeof(VertexCell *)));
-
- /* init. edge matrix pointers to NULL */
-
- for (loop = 0;loop <= NumVertices;loop++)
- for (loop2 = 0;loop2 <= NumVertices;loop2++)
- EdgeMatrix[loop][loop2] = NULL;
-
- Poly = Object->PolygonHead;
- while (!(Poly == NULL))
- {
- FindSmallest (Object,Poly,NumPolys);
- Poly = Poly->Next;
- }
-
- /* now, connect connect the t-vertices by adding vertices
- to polygons that have not been subdivided */
-
- CurrentPoly = Object->PolygonHead;
- while (!(CurrentPoly == NULL))
- {
- FixTVertices (CurrentPoly);
- CurrentPoly = CurrentPoly->Next;
- }
-
- /* move radiosities from patches to vertices */
-
-
- 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 += CurrentListPoly->Polygon->B.r;
- CurrentVert->B.g += CurrentListPoly->Polygon->B.g;
- CurrentVert->B.b += CurrentListPoly->Polygon->B.b;
- CurrentListPoly = CurrentListPoly->Rest;
- }
- CurrentVert->B.r /= (double)count;
- CurrentVert->B.g /= (double)count;
- CurrentVert->B.b /= (double)count;
-
-
- CurrentVert = CurrentVert->Next;
- }
-
- /* free memory of EdgeMatrix */
-
- for (loop = 0;loop < NumVertices + 1;loop++)
- free (EdgeMatrix[loop]);
- free (EdgeMatrix);
-
- }
-
-
-
-
-
-
-
-
-
-
-