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;
}
}
|