00001
00002
00003
00004
00005
00006
00007
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <math.h>
00012 #include "Inform.h"
00013 #include "utilities.h"
00014
00015 #define ISOSURFACE_INTERNAL 1
00016 #include "Isosurface.h"
00017 #include "VolumetricData.h"
00018
00019 #define MIN(X,Y) (((X)<(Y))? (X) : (Y))
00020 #define MAX(X,Y) (((X)>(Y))? (X) : (Y))
00021
00022 IsoSurface::IsoSurface(void) {}
00023
00024 void IsoSurface::clear(void) {
00025 numtriangles=0;
00026 v.clear();
00027 n.clear();
00028 c.clear();
00029 f.clear();
00030 }
00031
00032
00033 int IsoSurface::compute(const VolumetricData *data, float isovalue, int step) {
00034 int x, y, z;
00035 int tricount=0;
00036
00037 vol=data;
00038
00039
00040 vol->cell_axes(xax, yax, zax);
00041 vol->cell_dirs(xad, yad, zad);
00042
00043
00044 float vtmp[3];
00045 cross_prod(vtmp, xad, yad);
00046 if (dot_prod(vtmp, zad) < 0) {
00047 xad[0] *= -1;
00048 xad[1] *= -1;
00049 xad[2] *= -1;
00050 yad[0] *= -1;
00051 yad[1] *= -1;
00052 yad[2] *= -1;
00053 zad[0] *= -1;
00054 zad[1] *= -1;
00055 zad[2] *= -1;
00056 }
00057
00058 int i;
00059 int axisposnorms = 1;
00060 for (i=0; i<3; i++) {
00061 if (xad[i] < 0 || yad[i] < 0 || zad[i] < 0)
00062 axisposnorms = 0;
00063 }
00064
00065
00066 if (axisposnorms) {
00067 float xtmp[3] = {1.0f, 0.0f, 0.0f};
00068 if (dot_prod(xtmp, xax) != xax[0])
00069 axisposnorms = 0;
00070
00071 float ytmp[3] = {0.0f, 1.0f, 0.0f};
00072 if (dot_prod(ytmp, yax) != yax[1])
00073 axisposnorms = 0;
00074
00075 float ztmp[3] = {0.0f, 0.0f, 1.0f};
00076 if (dot_prod(ztmp, zax) != zax[2])
00077 axisposnorms = 0;
00078 }
00079
00080 if (axisposnorms) {
00081 tricount = DoGridPosNorms(isovalue, step);
00082 } else {
00083
00084 for (z=0; z<(vol->zsize - step); z+=step) {
00085 for (y=0; y<(vol->ysize - step); y+=step) {
00086 for (x=0; x<(vol->xsize - step); x+=step) {
00087 tricount += DoCellGeneral(x, y, z, isovalue, step);
00088 }
00089 }
00090 }
00091 }
00092
00093 return 1;
00094 }
00095
00096
00097
00098
00099
00100 int IsoSurface::DoGridPosNorms(float isovalue, int step) {
00101 GRIDCELL gc;
00102 TRIANGLE tris[5];
00103 int tricount=0;
00104 int globtricount=0;
00105 int row = vol->xsize;
00106 int plane = vol->xsize * vol->ysize;
00107 int rowstep = row*step;
00108 int planestep = plane*step;
00109
00110 int x, y, z;
00111 for (z=0; z<(vol->zsize - step); z+=step) {
00112 for (y=0; y<(vol->ysize - step); y+=step) {
00113 for (x=0; x<(vol->xsize - step); x+=step) {
00114 int addr = z*plane + y*row + x;
00115 gc.val[0] = vol->data[addr ];
00116 gc.val[1] = vol->data[addr + step ];
00117 gc.val[3] = vol->data[addr + rowstep ];
00118 gc.val[2] = vol->data[addr + step + rowstep ];
00119 gc.val[4] = vol->data[addr + planestep];
00120 gc.val[5] = vol->data[addr + step + planestep];
00121 gc.val[7] = vol->data[addr + rowstep + planestep];
00122 gc.val[6] = vol->data[addr + step + rowstep + planestep];
00123
00124
00125
00126 int cubeindex = 0;
00127 if (gc.val[0] < isovalue) cubeindex |= 1;
00128 if (gc.val[1] < isovalue) cubeindex |= 2;
00129 if (gc.val[2] < isovalue) cubeindex |= 4;
00130 if (gc.val[3] < isovalue) cubeindex |= 8;
00131 if (gc.val[4] < isovalue) cubeindex |= 16;
00132 if (gc.val[5] < isovalue) cubeindex |= 32;
00133 if (gc.val[6] < isovalue) cubeindex |= 64;
00134 if (gc.val[7] < isovalue) cubeindex |= 128;
00135
00136
00137 if (edgeTable[cubeindex] == 0)
00138 continue;
00139
00140 gc.cubeindex = cubeindex;
00141
00142 gc.p[0].x = (float) x;
00143 gc.p[0].y = (float) y;
00144 gc.p[0].z = (float) z;
00145 VOXEL_GRADIENT_FAST(vol, x, y, z, &gc.g[0].x)
00146
00147 gc.p[1].x = (float) x + step;
00148 gc.p[1].y = (float) y;
00149 gc.p[1].z = (float) z;
00150 VOXEL_GRADIENT_FAST(vol, x + step, y, z, &gc.g[1].x)
00151
00152 gc.p[3].x = (float) x;
00153 gc.p[3].y = (float) y + step;
00154 gc.p[3].z = (float) z;
00155 VOXEL_GRADIENT_FAST(vol, x, y + step, z, &gc.g[3].x)
00156
00157 gc.p[2].x = (float) x + step;
00158 gc.p[2].y = (float) y + step;
00159 gc.p[2].z = (float) z;
00160 VOXEL_GRADIENT_FAST(vol, x + step, y + step, z, &gc.g[2].x)
00161
00162 gc.p[4].x = (float) x;
00163 gc.p[4].y = (float) y;
00164 gc.p[4].z = (float) z + step;
00165 VOXEL_GRADIENT_FAST(vol, x, y, z + step, &gc.g[4].x)
00166
00167 gc.p[5].x = (float) x + step;
00168 gc.p[5].y = (float) y;
00169 gc.p[5].z = (float) z + step;
00170 VOXEL_GRADIENT_FAST(vol, x + step, y, z + step, &gc.g[5].x)
00171
00172 gc.p[7].x = (float) x;
00173 gc.p[7].y = (float) y + step;
00174 gc.p[7].z = (float) z + step;
00175 VOXEL_GRADIENT_FAST(vol, x, y + step, z + step, &gc.g[7].x)
00176
00177 gc.p[6].x = (float) x + step;
00178 gc.p[6].y = (float) y + step;
00179 gc.p[6].z = (float) z + step;
00180 VOXEL_GRADIENT_FAST(vol, x + step, y + step, z + step, &gc.g[6].x)
00181
00182
00183
00184
00185 tricount = Polygonise(gc, isovalue, (TRIANGLE *) &tris);
00186 globtricount += tricount;
00187
00188 int i;
00189 for (i=0; i<tricount; i++) {
00190 float xx, yy, zz;
00191 f.append(numtriangles * 3 );
00192 f.append(numtriangles * 3 + 1);
00193 f.append(numtriangles * 3 + 2);
00194 numtriangles++;
00195
00196
00197 xx = tris[i].p[0].x;
00198 yy = tris[i].p[0].y;
00199 zz = tris[i].p[0].z;
00200 v.append((float) vol->origin[0] + xx * xax[0]);
00201 v.append((float) vol->origin[1] + yy * yax[1]);
00202 v.append((float) vol->origin[2] + zz * zax[2]);
00203
00204 n.append(tris[i].n[0].x);
00205 n.append(tris[i].n[0].y);
00206 n.append(tris[i].n[0].z);
00207
00208 xx = tris[i].p[1].x;
00209 yy = tris[i].p[1].y;
00210 zz = tris[i].p[1].z;
00211 v.append((float) vol->origin[0] + xx * xax[0]);
00212 v.append((float) vol->origin[1] + yy * yax[1]);
00213 v.append((float) vol->origin[2] + zz * zax[2]);
00214 n.append(tris[i].n[1].x);
00215 n.append(tris[i].n[1].y);
00216 n.append(tris[i].n[1].z);
00217
00218 xx = tris[i].p[2].x;
00219 yy = tris[i].p[2].y;
00220 zz = tris[i].p[2].z;
00221 v.append((float) vol->origin[0] + xx * xax[0]);
00222 v.append((float) vol->origin[1] + yy * yax[1]);
00223 v.append((float) vol->origin[2] + zz * zax[2]);
00224 n.append(tris[i].n[2].x);
00225 n.append(tris[i].n[2].y);
00226 n.append(tris[i].n[2].z);
00227 }
00228 }
00229 }
00230 }
00231
00232 return globtricount;
00233 }
00234
00235
00236 int IsoSurface::DoCellGeneral(int x, int y, int z, float isovalue, int step) {
00237 GRIDCELL gc;
00238 int addr, row, plane, rowstep, planestep, tricount;
00239 TRIANGLE tris[5];
00240
00241 row = vol->xsize;
00242 plane = vol->xsize * vol->ysize;
00243 addr = z*plane + y*row + x;
00244 rowstep = row*step;
00245 planestep = plane*step;
00246
00247 gc.val[0] = vol->data[addr ];
00248 gc.val[1] = vol->data[addr + step ];
00249 gc.val[3] = vol->data[addr + rowstep ];
00250 gc.val[2] = vol->data[addr + step + rowstep ];
00251 gc.val[4] = vol->data[addr + planestep];
00252 gc.val[5] = vol->data[addr + step + planestep];
00253 gc.val[7] = vol->data[addr + rowstep + planestep];
00254 gc.val[6] = vol->data[addr + step + rowstep + planestep];
00255
00256
00257
00258 int cubeindex = 0;
00259 if (gc.val[0] < isovalue) cubeindex |= 1;
00260 if (gc.val[1] < isovalue) cubeindex |= 2;
00261 if (gc.val[2] < isovalue) cubeindex |= 4;
00262 if (gc.val[3] < isovalue) cubeindex |= 8;
00263 if (gc.val[4] < isovalue) cubeindex |= 16;
00264 if (gc.val[5] < isovalue) cubeindex |= 32;
00265 if (gc.val[6] < isovalue) cubeindex |= 64;
00266 if (gc.val[7] < isovalue) cubeindex |= 128;
00267
00268
00269 if (edgeTable[cubeindex] == 0)
00270 return 0;
00271
00272 gc.cubeindex = cubeindex;
00273
00274 gc.p[0].x = (float) x;
00275 gc.p[0].y = (float) y;
00276 gc.p[0].z = (float) z;
00277 VOXEL_GRADIENT_FAST(vol, x, y, z, &gc.g[0].x)
00278
00279 gc.p[1].x = (float) x + step;
00280 gc.p[1].y = (float) y;
00281 gc.p[1].z = (float) z;
00282 VOXEL_GRADIENT_FAST(vol, x + step, y, z, &gc.g[1].x)
00283
00284 gc.p[3].x = (float) x;
00285 gc.p[3].y = (float) y + step;
00286 gc.p[3].z = (float) z;
00287 VOXEL_GRADIENT_FAST(vol, x, y + step, z, &gc.g[3].x)
00288
00289 gc.p[2].x = (float) x + step;
00290 gc.p[2].y = (float) y + step;
00291 gc.p[2].z = (float) z;
00292 VOXEL_GRADIENT_FAST(vol, x + step, y + step, z, &gc.g[2].x)
00293
00294 gc.p[4].x = (float) x;
00295 gc.p[4].y = (float) y;
00296 gc.p[4].z = (float) z + step;
00297 VOXEL_GRADIENT_FAST(vol, x, y, z + step, &gc.g[4].x)
00298
00299 gc.p[5].x = (float) x + step;
00300 gc.p[5].y = (float) y;
00301 gc.p[5].z = (float) z + step;
00302 VOXEL_GRADIENT_FAST(vol, x + step, y, z + step, &gc.g[5].x)
00303
00304 gc.p[7].x = (float) x;
00305 gc.p[7].y = (float) y + step;
00306 gc.p[7].z = (float) z + step;
00307 VOXEL_GRADIENT_FAST(vol, x, y + step, z + step, &gc.g[7].x)
00308
00309 gc.p[6].x = (float) x + step;
00310 gc.p[6].y = (float) y + step;
00311 gc.p[6].z = (float) z + step;
00312 VOXEL_GRADIENT_FAST(vol, x + step, y + step, z + step, &gc.g[6].x)
00313
00314
00315
00316
00317 tricount = Polygonise(gc, isovalue, (TRIANGLE *) &tris);
00318
00319 int i;
00320 for (i=0; i<tricount; i++) {
00321 float xx, yy, zz;
00322 float xn, yn, zn;
00323
00324 f.append(numtriangles * 3 );
00325 f.append(numtriangles * 3 + 1);
00326 f.append(numtriangles * 3 + 2);
00327 numtriangles++;
00328
00329
00330 xx = tris[i].p[0].x;
00331 yy = tris[i].p[0].y;
00332 zz = tris[i].p[0].z;
00333
00334 v.append((float) vol->origin[0] + xx * xax[0] + yy * yax[0] + zz * zax[0]);
00335 v.append((float) vol->origin[1] + xx * xax[1] + yy * yax[1] + zz * zax[1]);
00336 v.append((float) vol->origin[2] + xx * xax[2] + yy * yax[2] + zz * zax[2]);
00337
00338 xn = tris[i].n[0].x;
00339 yn = tris[i].n[0].y;
00340 zn = tris[i].n[0].z;
00341 n.append((float) xn * xad[0] + yn * yad[0] + zn * zad[0]);
00342 n.append((float) xn * xad[1] + yn * yad[1] + zn * zad[1]);
00343 n.append((float) xn * xad[2] + yn * yad[2] + zn * zad[2]);
00344
00345 xx = tris[i].p[1].x;
00346 yy = tris[i].p[1].y;
00347 zz = tris[i].p[1].z;
00348 v.append((float) vol->origin[0] + xx * xax[0] + yy * yax[0] + zz * zax[0]);
00349 v.append((float) vol->origin[1] + xx * xax[1] + yy * yax[1] + zz * zax[1]);
00350 v.append((float) vol->origin[2] + xx * xax[2] + yy * yax[2] + zz * zax[2]);
00351 xn = tris[i].n[1].x;
00352 yn = tris[i].n[1].y;
00353 zn = tris[i].n[1].z;
00354 n.append((float) xn * xad[0] + yn * yad[0] + zn * zad[0]);
00355 n.append((float) xn * xad[1] + yn * yad[1] + zn * zad[1]);
00356 n.append((float) xn * xad[2] + yn * yad[2] + zn * zad[2]);
00357
00358 xx = tris[i].p[2].x;
00359 yy = tris[i].p[2].y;
00360 zz = tris[i].p[2].z;
00361 v.append((float) vol->origin[0] + xx * xax[0] + yy * yax[0] + zz * zax[0]);
00362 v.append((float) vol->origin[1] + xx * xax[1] + yy * yax[1] + zz * zax[1]);
00363 v.append((float) vol->origin[2] + xx * xax[2] + yy * yax[2] + zz * zax[2]);
00364 xn = tris[i].n[2].x;
00365 yn = tris[i].n[2].y;
00366 zn = tris[i].n[2].z;
00367 n.append((float) xn * xad[0] + yn * yad[0] + zn * zad[0]);
00368 n.append((float) xn * xad[1] + yn * yad[1] + zn * zad[1]);
00369 n.append((float) xn * xad[2] + yn * yad[2] + zn * zad[2]);
00370 }
00371
00372 return tricount;
00373 }
00374
00375
00376
00377
00378
00379 void IsoSurface::normalize() {
00380 int i;
00381 for (i=0; i<n.num(); i+=3) {
00382 vec_normalize(&n[i]);
00383 }
00384 }
00385
00386
00387 int IsoSurface::vertexfusion(const VolumetricData *data, int offset, int len) {
00388 int i, j, newverts, oldverts, faceverts, matchcount;
00389
00390 faceverts = f.num();
00391 oldverts = v.num() / 3;
00392
00393
00394 if (!faceverts || !oldverts)
00395 return 0;
00396
00397 int * vmap = new int[oldverts];
00398
00399 vmap[0] = 0;
00400 newverts = 1;
00401 matchcount = 0;
00402
00403 for (i=1; i<oldverts; i++) {
00404 int matchindex = -1;
00405 int start = ((newverts - offset) < 0) ? 0 : (newverts - offset);
00406 int end = ((start + len) > newverts) ? newverts : (start + len);
00407 int matched = 0;
00408 int vi = i * 3;
00409 for (j=start; j<end; j++) {
00410 int vj = j * 3;
00411 if (v[vi ] == v[vj ] &&
00412 v[vi+1] == v[vj+1] &&
00413 v[vi+2] == v[vj+2]) {
00414 matched = 1;
00415 matchindex = j;
00416 matchcount++;
00417 break;
00418 }
00419 }
00420
00421 if (matched) {
00422 vmap[i] = matchindex;
00423 } else {
00424 int vn = newverts * 3;
00425 v[vn ] = v[vi ];
00426 v[vn + 1] = v[vi + 1];
00427 v[vn + 2] = v[vi + 2];
00428 n[vn ] = n[vi ];
00429 n[vn + 1] = n[vi + 1];
00430 n[vn + 2] = n[vi + 2];
00431 vmap[i] = newverts;
00432 newverts++;
00433 }
00434 }
00435
00436
00437
00438
00439
00440 for (i=0; i<faceverts; i++) {
00441 f[i] = vmap[f[i]];
00442 }
00443 delete [] vmap;
00444
00445 v.truncatelastn((oldverts - newverts) * 3);
00446 n.truncatelastn((oldverts - newverts) * 3);
00447
00448 return 0;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 int IsoSurface::Polygonise(const GRIDCELL grid, const float isolevel, TRIANGLE *triangles) {
00462 int i,ntriang;
00463 int cubeindex = grid.cubeindex;
00464 XYZ vertlist[12];
00465 XYZ normlist[12];
00466
00467
00468 if (edgeTable[cubeindex] & 1)
00469 VertexInterp(isolevel, grid, 0, 1, &vertlist[0], &normlist[0]);
00470 if (edgeTable[cubeindex] & 2)
00471 VertexInterp(isolevel, grid, 1, 2, &vertlist[1], &normlist[1]);
00472 if (edgeTable[cubeindex] & 4)
00473 VertexInterp(isolevel, grid, 2, 3, &vertlist[2], &normlist[2]);
00474 if (edgeTable[cubeindex] & 8)
00475 VertexInterp(isolevel, grid, 3, 0, &vertlist[3], &normlist[3]);
00476 if (edgeTable[cubeindex] & 16)
00477 VertexInterp(isolevel, grid, 4, 5, &vertlist[4], &normlist[4]);
00478 if (edgeTable[cubeindex] & 32)
00479 VertexInterp(isolevel, grid, 5, 6, &vertlist[5], &normlist[5]);
00480 if (edgeTable[cubeindex] & 64)
00481 VertexInterp(isolevel, grid, 6, 7, &vertlist[6], &normlist[6]);
00482 if (edgeTable[cubeindex] & 128)
00483 VertexInterp(isolevel, grid, 7, 4, &vertlist[7], &normlist[7]);
00484 if (edgeTable[cubeindex] & 256)
00485 VertexInterp(isolevel, grid, 0, 4, &vertlist[8], &normlist[8]);
00486 if (edgeTable[cubeindex] & 512)
00487 VertexInterp(isolevel, grid, 1, 5, &vertlist[9], &normlist[9]);
00488 if (edgeTable[cubeindex] & 1024)
00489 VertexInterp(isolevel, grid, 2, 6, &vertlist[10], &normlist[10]);
00490 if (edgeTable[cubeindex] & 2048)
00491 VertexInterp(isolevel, grid, 3, 7, &vertlist[11], &normlist[11]);
00492
00493
00494 ntriang = 0;
00495 for (i=0;triTable[cubeindex][i]!=-1;i+=3) {
00496 triangles[ntriang].p[0] = vertlist[triTable[cubeindex][i ]];
00497 triangles[ntriang].p[1] = vertlist[triTable[cubeindex][i+1]];
00498 triangles[ntriang].p[2] = vertlist[triTable[cubeindex][i+2]];
00499 triangles[ntriang].n[0] = normlist[triTable[cubeindex][i ]];
00500 triangles[ntriang].n[1] = normlist[triTable[cubeindex][i+1]];
00501 triangles[ntriang].n[2] = normlist[triTable[cubeindex][i+2]];
00502 ntriang++;
00503 }
00504
00505 return ntriang;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 void IsoSurface::VertexInterp(float isolevel, const GRIDCELL grid, int ind1, int ind2, XYZ * vert, XYZ * norm) {
00516 XYZ p1 = grid.p[ind1];
00517 XYZ p2 = grid.p[ind2];
00518 XYZ n1 = grid.g[ind1];
00519 XYZ n2 = grid.g[ind2];
00520 float valp1 = grid.val[ind1];
00521 float valp2 = grid.val[ind2];
00522 float isodiffp1 = isolevel - valp1;
00523 float diffvalp2p1 = valp2 - valp1;
00524 float mu = 0.0f;
00525
00526
00527
00528
00529
00530
00531
00532 #if 0
00533 if (fabsf(isodiffp1) < 0.00001) {
00534 *vert = p1;
00535 *norm = n1;
00536 return;
00537 }
00538
00539 if (fabsf(isolevel-valp2) < 0.00001) {
00540 *vert = p2;
00541 *norm = n2;
00542 return;
00543 }
00544
00545 if (fabsf(diffvalp2p1) < 0.00001) {
00546 *vert = p1;
00547 *norm = n1;
00548 return;
00549 }
00550 #endif
00551
00552 if (fabsf(diffvalp2p1) > 0.0f)
00553 mu = isodiffp1 / diffvalp2p1;
00554
00555 #if 0
00556 if (mu > 1.0f)
00557 mu=1.0f;
00558
00559 if (mu < 0.0f)
00560 mu=0.0f;
00561 #endif
00562
00563 vert->x = p1.x + mu * (p2.x - p1.x);
00564 vert->y = p1.y + mu * (p2.y - p1.y);
00565 vert->z = p1.z + mu * (p2.z - p1.z);
00566
00567 norm->x = n1.x + mu * (n2.x - n1.x);
00568 norm->y = n1.y + mu * (n2.y - n1.y);
00569 norm->z = n1.z + mu * (n2.z - n1.z);
00570 }
00571
00572
00574 int IsoSurface::set_color_rgb3fv(const float *rgb) {
00575 int i;
00576 int numverts = v.num() / 3;
00577 for (i=0; i<numverts; i++) {
00578 c.append(rgb[0]);
00579 c.append(rgb[1]);
00580 c.append(rgb[2]);
00581 }
00582
00583 return 0;
00584 }
00585
00589 int IsoSurface::set_color_voltex_rgb3fv(const float *voltex) {
00590 int i;
00591 int numverts = v.num() / 3;
00592 int row = vol->xsize;
00593 int plane = vol->xsize * vol->ysize;
00594
00595 float xinv = 1.0f / xax[0];
00596 float yinv = 1.0f / yax[1];
00597 float zinv = 1.0f / zax[2];
00598 int xs = vol->xsize - 1;
00599 int ys = vol->ysize - 1;
00600 int zs = vol->zsize - 1;
00601
00602 for (i=0; i<numverts; i++) {
00603 int ind = i*3;
00604 float vx = ((v[ind ] - vol->origin[0]) * xinv);
00605 float vy = ((v[ind + 1] - vol->origin[1]) * yinv);
00606 float vz = ((v[ind + 2] - vol->origin[2]) * zinv);
00607
00608 int x = MIN(MAX(((int) vx), 0), xs);
00609 int y = MIN(MAX(((int) vy), 0), ys);
00610 int z = MIN(MAX(((int) vz), 0), zs);
00611
00612 int caddr = (z*plane + y*row + x)*3;
00613
00614 #if 0
00615
00616 float rgb[3];
00617 vec_copy(rgb, &voltex[caddr]);
00618
00619
00620 vec_normalize(rgb);
00621 #else
00622 float mux = (vx - x);
00623 float muy = (vy - y);
00624 float muz = (vz - z);
00625
00626 float c0[3], c1[3], c2[3], c3[3];
00627
00628 int caddrp1 = (x < xs) ? caddr+3 : caddr;
00629 c0[0] = (1-mux)*voltex[caddr ] + mux*voltex[caddrp1 ];
00630 c0[1] = (1-mux)*voltex[caddr + 1] + mux*voltex[caddrp1 + 1];
00631 c0[2] = (1-mux)*voltex[caddr + 2] + mux*voltex[caddrp1 + 2];
00632
00633 int yinc = (y < ys) ? row*3 : 0;
00634 caddr += yinc;
00635 caddrp1 += yinc;
00636 c1[0] = (1-mux)*voltex[caddr ] + mux*voltex[caddrp1 ];
00637 c1[1] = (1-mux)*voltex[caddr + 1] + mux*voltex[caddrp1 + 1];
00638 c1[2] = (1-mux)*voltex[caddr + 2] + mux*voltex[caddrp1 + 2];
00639
00640 int zinc = (z < zs) ? plane*3 : 0;
00641 caddr += zinc;
00642 caddrp1 += zinc;
00643 c3[0] = (1-mux)*voltex[caddr ] + mux*voltex[caddrp1 ];
00644 c3[1] = (1-mux)*voltex[caddr + 1] + mux*voltex[caddrp1 + 1];
00645 c3[2] = (1-mux)*voltex[caddr + 2] + mux*voltex[caddrp1 + 2];
00646
00647 caddr -= yinc;
00648 caddrp1 -= yinc;
00649 c2[0] = (1-mux)*voltex[caddr ] + mux*voltex[caddrp1 ];
00650 c2[1] = (1-mux)*voltex[caddr + 1] + mux*voltex[caddrp1 + 1];
00651 c2[2] = (1-mux)*voltex[caddr + 2] + mux*voltex[caddrp1 + 2];
00652
00653 float cz0[3];
00654 cz0[0] = (1-muy)*c0[0] + muy*c1[0];
00655 cz0[1] = (1-muy)*c0[1] + muy*c1[1];
00656 cz0[2] = (1-muy)*c0[2] + muy*c1[2];
00657
00658 float cz1[3];
00659 cz1[0] = (1-muy)*c2[0] + muy*c3[0];
00660 cz1[1] = (1-muy)*c2[1] + muy*c3[1];
00661 cz1[2] = (1-muy)*c2[2] + muy*c3[2];
00662
00663 float rgb[3];
00664 rgb[0] = (1-muz)*cz0[0] + muz*cz1[0];
00665 rgb[1] = (1-muz)*cz0[1] + muz*cz1[1];
00666 rgb[2] = (1-muz)*cz0[2] + muz*cz1[2];
00667 #endif
00668
00669 c.append(rgb[0]);
00670 c.append(rgb[1]);
00671 c.append(rgb[2]);
00672 }
00673
00674 return 0;
00675 }
00676
00677
00678
00679