1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg**
34f220fa62Smrg*/
35f220fa62Smrg/*
36f220fa62Smrg*/
37f220fa62Smrg
38f220fa62Smrg#include <stdlib.h>
39f220fa62Smrg#include <stdio.h>
40f220fa62Smrg#include "glimports.h"
41f220fa62Smrg#include "sampleComp.h"
42f220fa62Smrg#include "sampleCompTop.h"
43f220fa62Smrg#include "sampleCompBot.h"
44f220fa62Smrg#include "sampleCompRight.h"
45f220fa62Smrg
46f220fa62Smrg
47f220fa62Smrg
48f220fa62Smrg#define max(a,b) ((a>b)? a:b)
49f220fa62Smrg#define min(a,b) ((a>b)? b:a)
50f220fa62Smrg
51f220fa62Smrgvoid sampleConnectedComp(Real* topVertex, Real* botVertex,
52f220fa62Smrg		    vertexArray* leftChain,
53f220fa62Smrg		    Int leftStartIndex, Int leftEndIndex,
54f220fa62Smrg		    vertexArray* rightChain,
55f220fa62Smrg		    Int rightStartIndex, Int rightEndIndex,
56f220fa62Smrg		    gridBoundaryChain* leftGridChain,
57f220fa62Smrg		    gridBoundaryChain* rightGridChain,
58f220fa62Smrg		    Int gridIndex1, Int gridIndex2,
59f220fa62Smrg		    Int up_leftCornerWhere,
60f220fa62Smrg		    Int up_leftCornerIndex,
61f220fa62Smrg		    Int up_rightCornerWhere,
62f220fa62Smrg		    Int up_rightCornerIndex,
63f220fa62Smrg		    Int down_leftCornerWhere,
64f220fa62Smrg		    Int down_leftCornerIndex,
65f220fa62Smrg		    Int down_rightCornerWhere,
66f220fa62Smrg		    Int down_rightCornerIndex,
67f220fa62Smrg		    primStream* pStream,
68f220fa62Smrg		    rectBlockArray* rbArray
69f220fa62Smrg		    )
70f220fa62Smrg{
71f220fa62Smrg
72f220fa62Smrg sampleCompLeft(topVertex, botVertex,
73f220fa62Smrg		leftChain,
74f220fa62Smrg		leftStartIndex,	leftEndIndex,
75f220fa62Smrg		rightChain,
76f220fa62Smrg		rightStartIndex, rightEndIndex,
77f220fa62Smrg		leftGridChain,
78f220fa62Smrg		gridIndex1,
79f220fa62Smrg		gridIndex2,
80f220fa62Smrg		up_leftCornerWhere,
81f220fa62Smrg		up_leftCornerIndex,
82f220fa62Smrg		down_leftCornerWhere,
83f220fa62Smrg		down_leftCornerIndex,
84f220fa62Smrg		pStream);
85f220fa62Smrg
86f220fa62Smrg
87f220fa62Smrg sampleCompRight(topVertex, botVertex,
88f220fa62Smrg		 leftChain,
89f220fa62Smrg		 leftStartIndex, leftEndIndex,
90f220fa62Smrg		 rightChain,
91f220fa62Smrg		 rightStartIndex,
92f220fa62Smrg		 rightEndIndex,
93f220fa62Smrg		 rightGridChain,
94f220fa62Smrg		 gridIndex1, gridIndex2,
95f220fa62Smrg		 up_rightCornerWhere,
96f220fa62Smrg		 up_rightCornerIndex,
97f220fa62Smrg		 down_rightCornerWhere,
98f220fa62Smrg		 down_rightCornerIndex,
99f220fa62Smrg		 pStream);
100f220fa62Smrg
101f220fa62Smrg
102f220fa62Smrg sampleCompTop(topVertex,
103f220fa62Smrg		     leftChain,
104f220fa62Smrg		     leftStartIndex,
105f220fa62Smrg		     rightChain,
106f220fa62Smrg		     rightStartIndex,
107f220fa62Smrg		     leftGridChain,
108f220fa62Smrg		     rightGridChain,
109f220fa62Smrg		     gridIndex1,
110f220fa62Smrg		     up_leftCornerWhere,
111f220fa62Smrg		     up_leftCornerIndex,
112f220fa62Smrg		     up_rightCornerWhere,
113f220fa62Smrg		     up_rightCornerIndex,
114f220fa62Smrg		     pStream);
115f220fa62Smrg
116f220fa62Smrg sampleCompBot(botVertex,
117f220fa62Smrg		     leftChain,
118f220fa62Smrg		     leftEndIndex,
119f220fa62Smrg		     rightChain,
120f220fa62Smrg		     rightEndIndex,
121f220fa62Smrg		     leftGridChain,
122f220fa62Smrg		     rightGridChain,
123f220fa62Smrg		     gridIndex2,
124f220fa62Smrg		     down_leftCornerWhere,
125f220fa62Smrg		     down_leftCornerIndex,
126f220fa62Smrg		     down_rightCornerWhere,
127f220fa62Smrg		     down_rightCornerIndex,
128f220fa62Smrg		     pStream);
129f220fa62Smrg
130f220fa62Smrg
131f220fa62Smrg //the center
132f220fa62Smrg
133f220fa62Smrg rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2));
134f220fa62Smrg
135f220fa62Smrg
136f220fa62Smrg}
137f220fa62Smrg
138f220fa62Smrg/*notice that we need rightChain because the
139f220fa62Smrg *corners could be on the rightChain.
140f220fa62Smrg *here comp means component.
141f220fa62Smrg */
142f220fa62Smrgvoid sampleCompLeft(Real* topVertex, Real* botVertex,
143f220fa62Smrg		    vertexArray* leftChain,
144f220fa62Smrg		    Int leftStartIndex, Int leftEndIndex,
145f220fa62Smrg		    vertexArray* rightChain,
146f220fa62Smrg		    Int rightStartIndex, Int rightEndIndex,
147f220fa62Smrg		    gridBoundaryChain* leftGridChain,
148f220fa62Smrg		    Int gridIndex1, Int gridIndex2,
149f220fa62Smrg		    Int up_leftCornerWhere,
150f220fa62Smrg		    Int up_leftCornerIndex,
151f220fa62Smrg		    Int down_leftCornerWhere,
152f220fa62Smrg		    Int down_leftCornerIndex,
153f220fa62Smrg		    primStream* pStream)
154f220fa62Smrg{
155f220fa62Smrg  /*find out whether there is a trim vertex which is
156f220fa62Smrg   *inbetween the top and bot grid lines or not.
157f220fa62Smrg   */
158f220fa62Smrg  Int midIndex1;
159f220fa62Smrg  Int midIndex2;
160f220fa62Smrg  Int gridMidIndex1 = 0, gridMidIndex2 = 0;
161f220fa62Smrg  //midIndex1: array[i] <= v, array[i-1] > v
162f220fa62Smrg  //midIndex2: array[i] >= v, array[i+1] < v
163f220fa62Smrg  // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1)
164f220fa62Smrg  // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ??
165f220fa62Smrg  midIndex1 = leftChain->findIndexBelowGen(
166f220fa62Smrg					   leftGridChain->get_v_value(gridIndex1),
167f220fa62Smrg					   leftStartIndex,
168f220fa62Smrg					   leftEndIndex);
169f220fa62Smrg
170f220fa62Smrg  midIndex2 = -1; /*initilization*/
171f220fa62Smrg  if(midIndex1<= leftEndIndex && gridIndex1<gridIndex2)
172f220fa62Smrg    if(leftChain->getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2))
173f220fa62Smrg      {
174f220fa62Smrg	midIndex2 = leftChain->findIndexAboveGen(
175f220fa62Smrg						 leftGridChain->get_v_value(gridIndex2),
176f220fa62Smrg						 midIndex1, //midIndex1 <= midIndex2.
177f220fa62Smrg						 leftEndIndex);
178f220fa62Smrg	gridMidIndex1  = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1],
179f220fa62Smrg						gridIndex1, gridIndex2);
180f220fa62Smrg	gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1],
181f220fa62Smrg					       gridMidIndex1, gridIndex2);
182f220fa62Smrg      }
183f220fa62Smrg
184f220fa62Smrg
185f220fa62Smrg  /*to interprete the corner information*/
186f220fa62Smrg  Real* cornerTop;
187f220fa62Smrg  Real* cornerBot;
188f220fa62Smrg  Int cornerLeftStart;
189f220fa62Smrg  Int cornerLeftEnd;
190f220fa62Smrg  Int cornerRightUpEnd;
191f220fa62Smrg  Int cornerRightDownStart;
192f220fa62Smrg  if(up_leftCornerWhere == 0) /*left corner is on left chain*/
193f220fa62Smrg    {
194f220fa62Smrg      cornerTop = leftChain->getVertex(up_leftCornerIndex);
195f220fa62Smrg      cornerLeftStart = up_leftCornerIndex+1;
196f220fa62Smrg      cornerRightUpEnd = -1; /*no right*/
197f220fa62Smrg    }
198f220fa62Smrg  else if(up_leftCornerWhere == 1) /*left corner is on top*/
199f220fa62Smrg    {
200f220fa62Smrg      cornerTop = topVertex;
201f220fa62Smrg      cornerLeftStart = leftStartIndex;
202f220fa62Smrg      cornerRightUpEnd = -1; /*no right*/
203f220fa62Smrg    }
204f220fa62Smrg  else /*left corner is on right chain*/
205f220fa62Smrg    {
206f220fa62Smrg      cornerTop = topVertex;
207f220fa62Smrg      cornerLeftStart = leftStartIndex;
208f220fa62Smrg      cornerRightUpEnd = up_leftCornerIndex;
209f220fa62Smrg    }
210f220fa62Smrg
211f220fa62Smrg  if(down_leftCornerWhere == 0) /*left corner is on left chain*/
212f220fa62Smrg    {
213f220fa62Smrg      cornerBot = leftChain->getVertex(down_leftCornerIndex);
214f220fa62Smrg      cornerLeftEnd = down_leftCornerIndex-1;
215f220fa62Smrg      cornerRightDownStart = rightEndIndex+1; /*no right*/
216f220fa62Smrg    }
217f220fa62Smrg  else if(down_leftCornerWhere == 1) /*left corner is on bot*/
218f220fa62Smrg    {
219f220fa62Smrg      cornerBot = botVertex;
220f220fa62Smrg      cornerLeftEnd = leftEndIndex;
221f220fa62Smrg      cornerRightDownStart = rightEndIndex+1; /*no right*/
222f220fa62Smrg    }
223f220fa62Smrg  else /*left corner is on the right chian*/
224f220fa62Smrg    {
225f220fa62Smrg      cornerBot = botVertex;
226f220fa62Smrg      cornerLeftEnd = leftEndIndex;
227f220fa62Smrg      cornerRightDownStart = down_leftCornerIndex;
228f220fa62Smrg    }
229f220fa62Smrg
230f220fa62Smrg
231f220fa62Smrg
232f220fa62Smrg
233f220fa62Smrg  /*sample*/
234f220fa62Smrg  if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/
235f220fa62Smrg    {
236f220fa62Smrg
237f220fa62Smrg      sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1),
238f220fa62Smrg					leftChain,
239f220fa62Smrg					cornerLeftStart,
240f220fa62Smrg					midIndex1-1,
241f220fa62Smrg					leftGridChain,
242f220fa62Smrg					gridIndex1,
243f220fa62Smrg					gridMidIndex1,
244f220fa62Smrg					rightChain,
245f220fa62Smrg					rightStartIndex,
246f220fa62Smrg					cornerRightUpEnd,
247f220fa62Smrg					0, //no right down section
248f220fa62Smrg					-1,
249f220fa62Smrg					pStream);
250f220fa62Smrg
251f220fa62Smrg      sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2),
252f220fa62Smrg					cornerBot,
253f220fa62Smrg					leftChain,
254f220fa62Smrg					midIndex2+1,
255f220fa62Smrg					cornerLeftEnd,
256f220fa62Smrg					leftGridChain,
257f220fa62Smrg					gridMidIndex2,
258f220fa62Smrg					gridIndex2,
259f220fa62Smrg					rightChain,
260f220fa62Smrg					0, //no right up section
261f220fa62Smrg					-1,
262f220fa62Smrg					cornerRightDownStart,
263f220fa62Smrg					rightEndIndex,
264f220fa62Smrg					pStream);
265f220fa62Smrg
266f220fa62Smrg
267f220fa62Smrg      sampleLeftStripRecF(leftChain,
268f220fa62Smrg			  midIndex1,
269f220fa62Smrg			  midIndex2,
270f220fa62Smrg			  leftGridChain,
271f220fa62Smrg			  gridMidIndex1,
272f220fa62Smrg			  gridMidIndex2,
273f220fa62Smrg			  pStream);
274f220fa62Smrg    }
275f220fa62Smrg  else
276f220fa62Smrg    {
277f220fa62Smrg      sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot,
278f220fa62Smrg					leftChain,
279f220fa62Smrg					cornerLeftStart,
280f220fa62Smrg					cornerLeftEnd,
281f220fa62Smrg					leftGridChain,
282f220fa62Smrg					gridIndex1,
283f220fa62Smrg					gridIndex2,
284f220fa62Smrg					rightChain,
285f220fa62Smrg					rightStartIndex,
286f220fa62Smrg					cornerRightUpEnd,
287f220fa62Smrg					cornerRightDownStart,
288f220fa62Smrg					rightEndIndex,
289f220fa62Smrg					pStream);
290f220fa62Smrg    }
291f220fa62Smrg}
292f220fa62Smrg
293f220fa62Smrgvoid sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2],
294f220fa62Smrg				       vertexArray* leftChain,
295f220fa62Smrg				       Int leftStart,
296f220fa62Smrg				       Int leftEnd,
297f220fa62Smrg				       gridBoundaryChain* gridChain,
298f220fa62Smrg				       Int gridBeginIndex,
299f220fa62Smrg				       Int gridEndIndex,
300f220fa62Smrg				       vertexArray* rightChain,
301f220fa62Smrg				       Int rightUpBegin,
302f220fa62Smrg				       Int rightUpEnd,
303f220fa62Smrg				       Int rightDownBegin,
304f220fa62Smrg				       Int rightDownEnd,
305f220fa62Smrg				       primStream* pStream)
306f220fa62Smrg{
307f220fa62Smrg  Int i,j,k;
308f220fa62Smrg
309f220fa62Smrg  /*creat an array to store all the up and down secments of the right chain,
310f220fa62Smrg   *and the left end grid points
311f220fa62Smrg   *
312f220fa62Smrg   *although vertex array is a dynamic array, but to gain efficiency,
313f220fa62Smrg   *it is better to initiliza the exact array size
314f220fa62Smrg   */
315f220fa62Smrg  vertexArray vArray(gridEndIndex-gridBeginIndex+1 +
316f220fa62Smrg		     max(0,rightUpEnd - rightUpBegin+1)+
317f220fa62Smrg		     max(0,rightDownEnd - rightDownBegin+1));
318f220fa62Smrg
319f220fa62Smrg  /*append the vertices on the up section of thr right chain*/
320f220fa62Smrg  for(i=rightUpBegin; i<= rightUpEnd; i++)
321f220fa62Smrg    vArray.appendVertex(rightChain->getVertex(i));
322f220fa62Smrg
323f220fa62Smrg  /*append the vertices of the left extremal grid points,
324f220fa62Smrg   *and at the same time, perform triangulation for the stair cases
325f220fa62Smrg   */
326f220fa62Smrg  vArray.appendVertex(gridChain->get_vertex(gridBeginIndex));
327f220fa62Smrg
328f220fa62Smrg  for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; i++, k++)
329f220fa62Smrg    {
330f220fa62Smrg      vArray.appendVertex(gridChain->get_vertex(i));
331f220fa62Smrg
332f220fa62Smrg      /*output the fan of the grid points of the (i)th and (i-1)th grid line.
333f220fa62Smrg       */
334f220fa62Smrg      if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
335f220fa62Smrg	{
336f220fa62Smrg	  pStream->begin();
337f220fa62Smrg	  pStream->insert(gridChain->get_vertex(i-1));
338f220fa62Smrg	  for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
339f220fa62Smrg	    pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
340f220fa62Smrg	  pStream->end(PRIMITIVE_STREAM_FAN);
341f220fa62Smrg	}
342f220fa62Smrg      else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
343f220fa62Smrg	{
344f220fa62Smrg	  pStream->begin();
345f220fa62Smrg	  pStream->insert(gridChain->get_vertex(i));
346f220fa62Smrg	  for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
347f220fa62Smrg	    pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
348f220fa62Smrg	  pStream->end(PRIMITIVE_STREAM_FAN);
349f220fa62Smrg	}
350f220fa62Smrg      /*otherwisem, the two are equal, so there is no fan to outout*/
351f220fa62Smrg    }
352f220fa62Smrg
353f220fa62Smrg  /*then append all the vertices on the down section of the right chain*/
354f220fa62Smrg  for(i=rightDownBegin; i<= rightDownEnd; i++)
355f220fa62Smrg    vArray.appendVertex(rightChain->getVertex(i));
356f220fa62Smrg
357f220fa62Smrg  monoTriangulationRecGen(topVert, botVert,
358f220fa62Smrg			  leftChain, leftStart, leftEnd,
359f220fa62Smrg			  &vArray, 0, vArray.getNumElements()-1,
360f220fa62Smrg			  pStream);
361f220fa62Smrg
362f220fa62Smrg}
363f220fa62Smrg
364f220fa62Smrg
365f220fa62Smrg
366f220fa62Smrg
367f220fa62Smrg
368f220fa62Smrg
369f220fa62Smrg
370f220fa62Smrg
371f220fa62Smrg
372