File: impCubeTable.cpp

package info (click to toggle)
rss-glx 0.7.5-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 10,184 kB
  • ctags: 1,561
  • sloc: cpp: 11,577; ansic: 4,233; sh: 3,315; asm: 1,312; xml: 552; makefile: 194; perl: 49
file content (298 lines) | stat: -rw-r--r-- 7,735 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/*
 * Copyright (C) 2002  Terence M. Welsh
 * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
 *
 * Implicit is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as 
 * published by the Free Software Foundation.
 *
 * Implicit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "impCubeTable.h"

impCubeTable::impCubeTable ()
{
	cubetable = new int *[256];

	for (int i = 0; i < 256; i++)
		cubetable[i] = new int[17];

	ec[0][0] = 0;
	ec[0][1] = 1;
	ec[1][0] = 0;
	ec[1][1] = 2;
	ec[2][0] = 1;
	ec[2][1] = 3;
	ec[3][0] = 2;
	ec[3][1] = 3;
	ec[4][0] = 0;
	ec[4][1] = 4;
	ec[5][0] = 1;
	ec[5][1] = 5;
	ec[6][0] = 2;
	ec[6][1] = 6;
	ec[7][0] = 3;
	ec[7][1] = 7;
	ec[8][0] = 4;
	ec[8][1] = 5;
	ec[9][0] = 4;
	ec[9][1] = 6;
	ec[10][0] = 5;
	ec[10][1] = 7;
	ec[11][0] = 6;
	ec[11][1] = 7;

	vc[0][0] = 0;
	vc[0][1] = 1;
	vc[0][2] = 4;
	vc[1][0] = 0;
	vc[1][1] = 5;
	vc[1][2] = 2;
	vc[2][0] = 1;
	vc[2][1] = 3;
	vc[2][2] = 6;
	vc[3][0] = 2;
	vc[3][1] = 7;
	vc[3][2] = 3;
	vc[4][0] = 4;
	vc[4][1] = 9;
	vc[4][2] = 8;
	vc[5][0] = 5;
	vc[5][1] = 8;
	vc[5][2] = 10;
	vc[6][0] = 6;
	vc[6][1] = 11;
	vc[6][2] = 9;
	vc[7][0] = 7;
	vc[7][1] = 10;
	vc[7][2] = 11;

	makecubetable ();

	crawltable = new bool *[256];
	for (int i = 0; i < 256; i++)
		crawltable[i] = new bool[6];

	makecrawltable ();
}

// determines next edge extending from a vertex in counterclockwise order
int
  impCubeTable::nextedge (int vertex, int edge)
{
	if (vc[vertex][0] == edge)
		return (vc[vertex][1]);
	if (vc[vertex][1] == edge)
		return (vc[vertex][2]);
	if (vc[vertex][2] == edge)
		return (vc[vertex][0]);

	return (-1);
}

// adds a triangle strip description to the cube table
void impCubeTable::addtotable (int row, int edgecount, int *edgelist)
{
	static int lastrow = -1;
	static int totalcount;

	if (row != lastrow)
		totalcount = 0;

	// enter the number of vertices into the cubetable
	cubetable[row][totalcount] = edgecount;

	// The edges are listed in counterclockwise order in the edgelist.
	// Notice how they are added to the cubetable out of order, in
	// a zig-zag pattern the way a triangle strip is drawn.
	// There can be at most 7 vertices in one of these triangle strips.
	switch (edgecount) {
	case 3:
		cubetable[row][totalcount + 1] = edgelist[0];
		cubetable[row][totalcount + 2] = edgelist[1];
		cubetable[row][totalcount + 3] = edgelist[2];
		break;
	case 4:
		cubetable[row][totalcount + 1] = edgelist[0];
		cubetable[row][totalcount + 2] = edgelist[1];
		cubetable[row][totalcount + 3] = edgelist[3];
		cubetable[row][totalcount + 4] = edgelist[2];
		break;
	case 5:
		cubetable[row][totalcount + 1] = edgelist[0];
		cubetable[row][totalcount + 2] = edgelist[1];
		cubetable[row][totalcount + 3] = edgelist[4];
		cubetable[row][totalcount + 4] = edgelist[2];
		cubetable[row][totalcount + 5] = edgelist[3];
		break;
	case 6:
		cubetable[row][totalcount + 1] = edgelist[0];
		cubetable[row][totalcount + 2] = edgelist[1];
		cubetable[row][totalcount + 3] = edgelist[5];
		cubetable[row][totalcount + 4] = edgelist[2];
		cubetable[row][totalcount + 5] = edgelist[4];
		cubetable[row][totalcount + 6] = edgelist[3];
		break;
	case 7:
		cubetable[row][totalcount + 1] = edgelist[0];
		cubetable[row][totalcount + 2] = edgelist[1];
		cubetable[row][totalcount + 3] = edgelist[6];
		cubetable[row][totalcount + 4] = edgelist[2];
		cubetable[row][totalcount + 5] = edgelist[5];
		cubetable[row][totalcount + 6] = edgelist[3];
		cubetable[row][totalcount + 7] = edgelist[4];
		break;
	}

	totalcount += (edgecount + 1);
	lastrow = row;
}

void impCubeTable::makecubetable ()
{
	int i, j, k;
	int currentvertex;
	int currentedge;
	bool vertices[8];	// true if on low side of gradient (outside of surface)
	bool edges[12];
	bool edgesdone[12];
	int edgelist[7];	// final list of egdes used in a triangle strip
	int edgecount;

	// Set cubetable values to zero
	// A zero will indicate that there are no more triangle strips to build
	for (i = 0; i < 256; i++) {
		for (j = 0; j < 17; j++) {
			cubetable[i][j] = 0;
		}
	}

	// For each vertex combination
	for (i = 0; i < 256; i++) {
		// identify the vertices on the low side of the gradient
		int andbit;

		for (j = 0; j < 8; j++) {
			andbit = 1;
			for (k = 0; k < j; k++)
				andbit *= 2;
			if (i & andbit)
				vertices[j] = 1;
			else
				vertices[j] = 0;
		}

		// Identify the edges that cross threshold value
		// These are edges that connect 1 turned-on and 1 turned-off vertex
		for (j = 0; j < 12; j++) {
			if ((vertices[ec[j][0]] + vertices[ec[j][1]]) == 1)
				edges[j] = 1;
			else
				edges[j] = 0;
			edgesdone[j] = 0;	// no edges have been used yet
		}

		// Construct lists of edges that form triangle strips
		// try starting from each edge (no need to try last 2 edges)
		for (j = 0; j < 10; j++) {
			currentedge = j;
			edgecount = 0;
			// if this edge contains a surface vertex and hasn't been used
			while (edges[currentedge] && !edgesdone[currentedge]) {
				// add edge to list
				edgelist[edgecount] = currentedge;
				edgecount++;
				edgesdone[currentedge] = 1;
				// find that edge's vertex on low side of gradient
				if (vertices[ec[currentedge][0]])
					currentvertex = ec[currentedge][0];
				else
					currentvertex = ec[currentedge][1];
				// move along gradiant boundary to find next edge
				currentedge = nextedge (currentvertex, currentedge);
				while (!edges[currentedge]) {
					if (currentvertex != ec[currentedge][0])
						currentvertex = ec[currentedge][0];
					else
						currentvertex = ec[currentedge][1];
					currentedge = nextedge (currentvertex, currentedge);
				}
			}
			// if a surface has been created add it to the table
			// and start over to try to make another surface
			if (edgecount)
				addtotable (i, edgecount, edgelist);
		}
	}
}

void impCubeTable::makecrawltable ()
{
	int i, j, k;
	bool vertices[8];	// vertices below gradient threshold get turned on
	bool edges[12];		// edges that cross gradient threshold get turned on

	// For each vertex combination
	for (i = 0; i < 256; i++) {
		// identify the vertices on the low side of the gradient
		int andbit;

		for (j = 0; j < 8; j++) {
			andbit = 1;
			for (k = 0; k < j; k++)
				andbit *= 2;
			if (i & andbit)
				vertices[j] = 1;
			else
				vertices[j] = 0;
		}

		// Identify the edges that cross threshold value
		// These are edges that connect 1 turned-on and 1 turned-off vertex
		for (j = 0; j < 12; j++) {
			if ((vertices[ec[j][0]] + vertices[ec[j][1]]) == 1)
				edges[j] = 1;
			else
				edges[j] = 0;
		}

		// -x
		if (edges[0] || edges[1] || edges[2] || edges[3])
			crawltable[i][0] = true;
		else
			crawltable[i][0] = false;
		// +x
		if (edges[8] || edges[9] || edges[10] || edges[11])
			crawltable[i][1] = true;
		else
			crawltable[i][1] = false;
		// -y
		if (edges[0] || edges[4] || edges[5] || edges[8])
			crawltable[i][2] = true;
		else
			crawltable[i][2] = false;
		// +y
		if (edges[3] || edges[6] || edges[7] || edges[11])
			crawltable[i][3] = true;
		else
			crawltable[i][3] = false;
		// -z
		if (edges[1] || edges[4] || edges[6] || edges[9])
			crawltable[i][4] = true;
		else
			crawltable[i][4] = false;
		// +z
		if (edges[2] || edges[5] || edges[7] || edges[10])
			crawltable[i][5] = true;
		else
			crawltable[i][5] = false;
	}
}