2
* Copyright (C) 2002 Terence M. Welsh
3
* Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
5
* Implicit is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Implicit is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
#include "impCubeVolume.h"
21
impCubeVolume::impCubeVolume ()
29
thecubetable = new impCubeTable ();
30
cubetable = thecubetable->cubetable;
31
crawltable = thecubetable->crawltable;
34
impCubeVolume::~impCubeVolume ()
42
impCubeVolume::init (int width, int height, int length, float cw)
49
/*for(i=0; i<=width; i++){
50
for(j=0; j<=height; j++){
51
for(k=0; k<=length; k++)
52
delete[] corners[i][j][k];
53
delete[] corners[i][j];
66
// calculate position of left-bottom-front corner
68
lbf[0] = -float (width) * cubewidth * 0.5f;
69
lbf[1] = -float (height) * cubewidth * 0.5f;
70
lbf[2] = -float (length) * cubewidth * 0.5f;
72
// allocate cubeinfo memory and set cube positions
73
cubes = new cubeinfo **[width];
74
for (i = 0; i < width; i++) {
75
cubes[i] = new cubeinfo *[height];
76
for (j = 0; j < height; j++) {
77
cubes[i][j] = new cubeinfo[length];
78
for (k = 0; k < length; k++) {
79
cubes[i][j][k].done = 0;
80
cubes[i][j][k].x = lbf[0] + (cubewidth * (float (i) + 0.5f));
81
cubes[i][j][k].y = lbf[1] + (cubewidth * (float (j) + 0.5f));
82
cubes[i][j][k].z = lbf[2] + (cubewidth * (float (k) + 0.5f));
87
// "corners" will store the position of each corner
88
// plus the value of the gradient at that location
89
corners = new cornerinfo **[width + 1];
90
for (i = 0; i <= width; i++) {
91
corners[i] = new cornerinfo *[height + 1];
92
for (j = 0; j <= height; j++) {
93
corners[i][j] = new cornerinfo[length + 1];
94
for (k = 0; k <= length; k++) {
95
corners[i][j][k].done = 0;
96
corners[i][j][k].position[0] = lbf[0] + (cubewidth * float (i));
97
corners[i][j][k].position[1] = lbf[1] + (cubewidth * float (j));
98
corners[i][j][k].position[2] = lbf[2] + (cubewidth * float (k));
102
/*corners = new float***[width+1];
103
for(i=0; i<=width; i++){
104
corners[i] = new float**[height+1];
105
for(j=0; j<=height; j++){
106
corners[i][j] = new float*[length+1];
107
for(k=0; k<=length; k++)
108
corners[i][j][k] = new float[4];
112
for(i=0; i<=width; i++){
113
for(j=0; j<=height; j++){
114
for(k=0; k<=length; k++){
115
corners[i][j][k][0] = lbf[0] + (cubewidth * float(i));
116
corners[i][j][k][1] = lbf[1] + (cubewidth * float(j));
117
corners[i][j][k][2] = lbf[2] + (cubewidth * float(k));
122
edges = new edgeinfo ***[3]; // a set of edges aligned with each axis
123
// edges along x-axis
124
edges[0] = new edgeinfo **[width];
125
for (i = 0; i < width; i++) {
126
edges[0][i] = new edgeinfo *[height + 1];
127
for (j = 0; j <= height; j++) {
128
edges[0][i][j] = new edgeinfo[length + 1];
129
for (k = 0; k <= length; k++)
130
edges[0][i][j][k].done = 0;
133
// edges along y-axis
134
edges[1] = new edgeinfo **[width + 1];
135
for (i = 0; i <= width; i++) {
136
edges[1][i] = new edgeinfo *[height];
137
for (j = 0; j < height; j++) {
138
edges[1][i][j] = new edgeinfo[length + 1];
139
for (k = 0; k <= length; k++)
140
edges[1][i][j][k].done = 0;
143
// edges along z-axis
144
edges[2] = new edgeinfo **[width + 1];
145
for (i = 0; i <= width; i++) {
146
edges[2][i] = new edgeinfo *[height + 1];
147
for (j = 0; j <= height; j++) {
148
edges[2][i][j] = new edgeinfo[length];
149
for (k = 0; k < length; k++)
150
edges[2][i][j][k].done = 0;
155
void impCubeVolume::make_surface ()
162
// find gradient value at every corner
163
for (i = 0; i <= whl[0]; i++) {
164
for (j = 0; j <= whl[1]; j++) {
165
for (k = 0; k <= whl[2]; k++)
166
corners[i][j][k].value = function (corners[i][j][k].position);
170
// polygonize surface
171
for (i = 0; i < whl[0]; i++) {
172
for (j = 0; j < whl[1]; j++) {
173
for (k = 0; k < whl[2]; k++) {
174
cubes[i][j][k].index = findcubetableindex (i, j, k);
175
polygonize (i, j, k);
180
// zero-out edges' done labels
181
for (i = 0; i < whl[0]; i++) {
182
for (j = 0; j <= whl[1]; j++) {
183
for (k = 0; k <= whl[2]; k++) {
184
edges[0][i][j][k].done = 0;
188
for (i = 0; i <= whl[0]; i++) {
189
for (j = 0; j < whl[1]; j++) {
190
for (k = 0; k <= whl[2]; k++) {
191
edges[1][i][j][k].done = 0;
195
for (i = 0; i <= whl[0]; i++) {
196
for (j = 0; j <= whl[1]; j++) {
197
for (k = 0; k < whl[2]; k++) {
198
edges[2][i][j][k].done = 0;
204
void impCubeVolume::make_surface (float eyex, float eyey, float eyez)
208
cubelistelem *currentcube;
209
float xdist, ydist, zdist;
214
// find gradient value at every corner
215
for (i = 0; i <= whl[0]; i++) {
216
for (j = 0; j <= whl[1]; j++) {
217
for (k = 0; k <= whl[2]; k++)
218
corners[i][j][k].value = function (corners[i][j][k].position);
222
// erase list from last frame
225
// polygonize surface
226
for (i = 0; i < whl[0]; i++) {
227
for (j = 0; j < whl[1]; j++) {
228
for (k = 0; k < whl[2]; k++) {
229
index = findcubetableindex (i, j, k);
230
if (index != 0 && index != 255) {
231
cubelist.push_back (cubelistelem (index));
232
currentcube = &(cubelist.back ());
233
currentcube->position[0] = i;
234
currentcube->position[1] = j;
235
currentcube->position[2] = k;
236
xdist = cubes[i][j][k].x - eyex;
237
ydist = cubes[i][j][k].y - eyey;
238
zdist = cubes[i][j][k].z - eyez;
239
currentcube->depth = xdist * xdist + ydist * ydist + zdist * zdist;
248
// polygonize surface
251
// zero-out edges' done labels
252
for (i = 0; i < whl[0]; i++) {
253
for (j = 0; j <= whl[1]; j++) {
254
for (k = 0; k <= whl[2]; k++) {
255
edges[0][i][j][k].done = 0;
259
for (i = 0; i <= whl[0]; i++) {
260
for (j = 0; j < whl[1]; j++) {
261
for (k = 0; k <= whl[2]; k++) {
262
edges[1][i][j][k].done = 0;
266
for (i = 0; i <= whl[0]; i++) {
267
for (j = 0; j <= whl[1]; j++) {
268
for (k = 0; k < whl[2]; k++) {
269
edges[2][i][j][k].done = 0;
275
void impCubeVolume::make_surface (std::list < impCrawlPoint > crawlpointlist)
284
// crawl from every crawl point to create the surface
285
std::list < impCrawlPoint >::iterator crawliter = crawlpointlist.begin ();
286
while (crawliter != crawlpointlist.end ()) {
287
// find cube corresponding to crawl point
288
i = int ((crawliter->position[0] - lbf[0]) / cubewidth);
294
j = int ((crawliter->position[1] - lbf[1]) / cubewidth);
300
k = int ((crawliter->position[2] - lbf[2]) / cubewidth);
307
// escape if starting on a finished cube
309
while (!crawlpointexit) {
310
if (cubes[i][j][k].done)
311
crawlpointexit = 1; // escape if starting on a finished cube
312
else { // find index for this cube
313
findcornervalues (i, j, k);
314
index = findcubetableindex (i, j, k);
315
// save index for uncrawling
316
cubes[i][j][k].index = index;
317
if (index == 255) // escape if outside surface
320
if (index == 0) { // this cube is inside volume
321
cubes[i][j][k].done = 1;
322
i--; // step to an adjacent cube and start over
323
if (i < 0) // escape if you step outside of volume
326
crawl_nosort (i, j, k);
336
// crawl from every crawl point to zero-out done flags
337
crawliter = crawlpointlist.begin ();
338
while (crawliter != crawlpointlist.end ()) {
339
// find cube corresponding to crawl point
340
i = int ((crawliter->position[0] - lbf[0]) / cubewidth);
346
j = int ((crawliter->position[1] - lbf[1]) / cubewidth);
352
k = int ((crawliter->position[2] - lbf[2]) / cubewidth);
359
// escape if starting on a finished cube
361
while (!crawlpointexit) {
362
if (!(cubes[i][j][k].done))
363
crawlpointexit = 1; // escape if starting on an unused cube
365
index = cubes[i][j][k].index; //findcubetableindex(i, j, k);
367
cubes[i][j][k].done = 0;
368
corners[i][j][k].done = 0;
369
corners[i][j][k + 1].done = 0;
370
corners[i][j + 1][k].done = 0;
371
corners[i][j + 1][k + 1].done = 0;
372
corners[i + 1][j][k].done = 0;
373
corners[i + 1][j][k + 1].done = 0;
374
corners[i + 1][j + 1][k].done = 0;
375
corners[i + 1][j + 1][k + 1].done = 0;
376
i--; // step to an adjacent cube and start over
377
if (i < 0) // escape if you step outside of volume
390
void impCubeVolume::make_surface (float eyex, float eyey, float eyez, std::list < impCrawlPoint > crawlpointlist)
395
float xdist, ydist, zdist;
400
// erase list from last fram
403
// crawl from every crawl point to create the surface
404
std::list < impCrawlPoint >::iterator crawliter = crawlpointlist.begin ();
405
while (crawliter != crawlpointlist.end ()) {
406
// find cube corresponding to crawl point
407
i = int ((crawliter->position[0] - lbf[0]) / cubewidth);
413
j = int ((crawliter->position[1] - lbf[1]) / cubewidth);
419
k = int ((crawliter->position[2] - lbf[2]) / cubewidth);
426
// escape if starting on a finished cube
428
while (!crawlpointexit) {
429
if (cubes[i][j][k].done)
430
crawlpointexit = 1; // escape if starting on a finished cube
431
else { // find index for this cube
432
findcornervalues (i, j, k);
433
index = findcubetableindex (i, j, k);
434
// save index for uncrawling
435
cubes[i][j][k].index = index;
436
if (index == 255) // escape if outside surface
439
if (index == 0) { // this cube is inside volume
440
cubes[i][j][k].done = 1;
441
i--; // step to an adjacent cube and start over
442
if (i < 0) // escape if you step outside of volume
445
crawl_sort (i, j, k);
456
std::list < cubelistelem >::iterator cubeiter = cubelist.begin ();
457
while (cubeiter != cubelist.end ()) {
458
i = cubeiter->position[0];
459
j = cubeiter->position[1];
460
k = cubeiter->position[2];
461
xdist = cubes[i][j][k].x - eyex;
462
ydist = cubes[i][j][k].y - eyey;
463
zdist = cubes[i][j][k].z - eyez;
464
cubeiter->depth = xdist * xdist + ydist * ydist + zdist * zdist;
469
// polygonize surface
472
// crawl from every crawl point to zero-out done flags
473
crawliter = crawlpointlist.begin ();
474
while (crawliter != crawlpointlist.end ()) {
475
// find cube corresponding to crawl point
476
i = int ((crawliter->position[0] - lbf[0]) / cubewidth);
482
j = int ((crawliter->position[1] - lbf[1]) / cubewidth);
488
k = int ((crawliter->position[2] - lbf[2]) / cubewidth);
495
// escape if starting on a finished cube
497
while (!crawlpointexit) {
498
if (!(cubes[i][j][k].done))
499
crawlpointexit = 1; // escape if starting on an unused cube
501
index = cubes[i][j][k].index;
503
cubes[i][j][k].done = 0;
504
corners[i][j][k].done = 0;
505
corners[i][j][k + 1].done = 0;
506
corners[i][j + 1][k].done = 0;
507
corners[i][j + 1][k + 1].done = 0;
508
corners[i + 1][j][k].done = 0;
509
corners[i + 1][j][k + 1].done = 0;
510
corners[i + 1][j + 1][k].done = 0;
511
corners[i + 1][j + 1][k + 1].done = 0;
512
i--; // step to an adjacent cube and start over
513
if (i < 0) // escape if you step outside of volume
526
// calculate index into cubetable
527
inline int impCubeVolume::findcubetableindex (int x, int y, int z)
532
if (corners[x][y][z].value < surfacevalue)
534
if (corners[x][y][z + 1].value < surfacevalue)
536
if (corners[x][y + 1][z].value < surfacevalue)
538
if (corners[x][y + 1][z + 1].value < surfacevalue)
540
if (corners[x + 1][y][z].value < surfacevalue)
542
if (corners[x + 1][y][z + 1].value < surfacevalue)
544
if (corners[x + 1][y + 1][z].value < surfacevalue)
546
if (corners[x + 1][y + 1][z + 1].value < surfacevalue)
552
inline void impCubeVolume::crawl_nosort (int x, int y, int z)
554
findcornervalues (x, y, z);
555
int index = findcubetableindex (x, y, z);
557
// quit if this cube has been done or does not intersect surface
558
if (cubes[x][y][z].done || index == 0 || index == 255)
561
// save index for polygonizing and uncrawling
562
cubes[x][y][z].index = index;
564
// polygonize this cube if it intersects surface
565
polygonize (x, y, z);
567
// mark this cube as completed
568
cubes[x][y][z].done = 1;
570
// polygonize adjacent cubes
571
if (crawltable[index][0] && x > 0)
572
crawl_nosort (x - 1, y, z);
573
if (crawltable[index][1] && x < whl[0] - 1)
574
crawl_nosort (x + 1, y, z);
575
if (crawltable[index][2] && y > 0)
576
crawl_nosort (x, y - 1, z);
577
if (crawltable[index][3] && y < whl[1] - 1)
578
crawl_nosort (x, y + 1, z);
579
if (crawltable[index][4] && z > 0)
580
crawl_nosort (x, y, z - 1);
581
if (crawltable[index][5] && z < whl[2] - 1)
582
crawl_nosort (x, y, z + 1);
585
inline void impCubeVolume::crawl_sort (int x, int y, int z)
587
findcornervalues (x, y, z);
588
int index = findcubetableindex (x, y, z);
590
// quit if this cube has been done or does not intersect surface
591
if (cubes[x][y][z].done || index == 0 || index == 255)
594
// save index for uncrawling
595
cubes[x][y][z].index = index;
597
// mark this cube as completed
598
cubes[x][y][z].done = 1;
601
cubelist.push_back (cubelistelem (index));
602
cubelistelem *currentcube = &(cubelist.back ());
604
currentcube->position[0] = x;
605
currentcube->position[1] = y;
606
currentcube->position[2] = z;
608
// polygonize adjacent cubes
609
if (crawltable[index][0] && x > 0)
610
crawl_sort (x - 1, y, z);
611
if (crawltable[index][1] && x < whl[0] - 1)
612
crawl_sort (x + 1, y, z);
613
if (crawltable[index][2] && y > 0)
614
crawl_sort (x, y - 1, z);
615
if (crawltable[index][3] && y < whl[1] - 1)
616
crawl_sort (x, y + 1, z);
617
if (crawltable[index][4] && z > 0)
618
crawl_sort (x, y, z - 1);
619
if (crawltable[index][5] && z < whl[2] - 1)
620
crawl_sort (x, y, z + 1);
623
inline void impCubeVolume::uncrawl (int x, int y, int z)
625
if (!(cubes[x][y][z].done))
628
corners[x][y][z].done = 0;
629
corners[x][y][z + 1].done = 0;
630
corners[x][y + 1][z].done = 0;
631
corners[x][y + 1][z + 1].done = 0;
632
corners[x + 1][y][z].done = 0;
633
corners[x + 1][y][z + 1].done = 0;
634
corners[x + 1][y + 1][z].done = 0;
635
corners[x + 1][y + 1][z + 1].done = 0;
637
cubes[x][y][z].done = 0;
639
edges[0][x][y][z].done = 0;
640
edges[0][x][y + 1][z].done = 0;
641
edges[0][x][y][z + 1].done = 0;
642
edges[0][x][y + 1][z + 1].done = 0;
643
edges[1][x][y][z].done = 0;
644
edges[1][x + 1][y][z].done = 0;
645
edges[1][x][y][z + 1].done = 0;
646
edges[1][x + 1][y][z + 1].done = 0;
647
edges[2][x][y][z].done = 0;
648
edges[2][x + 1][y][z].done = 0;
649
edges[2][x][y + 1][z].done = 0;
650
edges[2][x + 1][y + 1][z].done = 0;
652
// uncrawl adjacent cubes
653
int index = cubes[x][y][z].index;
655
if (crawltable[index][0] && x > 0)
656
uncrawl (x - 1, y, z);
657
if (crawltable[index][1] && x < whl[0] - 1)
658
uncrawl (x + 1, y, z);
659
if (crawltable[index][2] && y > 0)
660
uncrawl (x, y - 1, z);
661
if (crawltable[index][3] && y < whl[1] - 1)
662
uncrawl (x, y + 1, z);
663
if (crawltable[index][4] && z > 0)
664
uncrawl (x, y, z - 1);
665
if (crawltable[index][5] && z < whl[2] - 1)
666
uncrawl (x, y, z + 1);
669
// polygonize an individual cube
670
inline void impCubeVolume::polygonize (int x, int y, int z)
672
// stores data for computed triangle strips
674
static float data[42];
675
static int index, counter;
677
static int copysize = 6 * sizeof (float);
679
// find index into cubetable
680
index = cubes[x][y][z].index;
683
nedges = cubetable[index][counter];
684
while (nedges != 0) {
685
for (i = 0; i < nedges; i++) {
686
// generate vertex position and normal data
687
switch (cubetable[index][i + counter + 1]) {
689
findvert (2, x, y, z);
690
memcpy (&data[i * 6], edges[2][x][y][z].data, copysize);
693
findvert (1, x, y, z);
694
memcpy (&data[i * 6], edges[1][x][y][z].data, copysize);
697
findvert (1, x, y, z + 1);
698
memcpy (&data[i * 6], edges[1][x][y][z + 1].data, copysize);
701
findvert (2, x, y + 1, z);
702
memcpy (&data[i * 6], edges[2][x][y + 1][z].data, copysize);
705
findvert (0, x, y, z);
706
memcpy (&data[i * 6], edges[0][x][y][z].data, copysize);
709
findvert (0, x, y, z + 1);
710
memcpy (&data[i * 6], edges[0][x][y][z + 1].data, copysize);
713
findvert (0, x, y + 1, z);
714
memcpy (&data[i * 6], edges[0][x][y + 1][z].data, copysize);
717
findvert (0, x, y + 1, z + 1);
718
memcpy (&data[i * 6], edges[0][x][y + 1][z + 1].data, copysize);
721
findvert (2, x + 1, y, z);
722
memcpy (&data[i * 6], edges[2][x + 1][y][z].data, copysize);
725
findvert (1, x + 1, y, z);
726
memcpy (&data[i * 6], edges[1][x + 1][y][z].data, copysize);
729
findvert (1, x + 1, y, z + 1);
730
memcpy (&data[i * 6], edges[1][x + 1][y][z + 1].data, copysize);
733
findvert (2, x + 1, y + 1, z);
734
memcpy (&data[i * 6], edges[2][x + 1][y + 1][z].data, copysize);
737
surface->addstrip (nedges, data);
738
counter += (nedges + 1);
739
nedges = cubetable[index][counter];
743
// polygonize a list of cubes stored in "cubelist"
744
inline void impCubeVolume::polygonize ()
746
// stores data for computed triangle strips
749
static float data[42];
750
static int index, counter;
752
static int copysize = 6 * sizeof (float);
754
// polygonize in reverse order so that the farthest cube
755
// is drawn first and the closest is drawn last
756
std::list < cubelistelem >::iterator iter = cubelist.end ();
757
while (iter != cubelist.begin ()) {
760
x = iter->position[0];
761
y = iter->position[1];
762
z = iter->position[2];
764
// find index into cubetable
768
nedges = cubetable[index][counter];
769
while (nedges != 0) {
770
for (i = 0; i < nedges; i++) {
771
// generate vertex position and normal data
772
switch (cubetable[index][i + counter + 1]) {
774
findvert (2, x, y, z);
775
memcpy (&data[i * 6], edges[2][x][y][z].data, copysize);
778
findvert (1, x, y, z);
779
memcpy (&data[i * 6], edges[1][x][y][z].data, copysize);
782
findvert (1, x, y, z + 1);
783
memcpy (&data[i * 6], edges[1][x][y][z + 1].data, copysize);
786
findvert (2, x, y + 1, z);
787
memcpy (&data[i * 6], edges[2][x][y + 1][z].data, copysize);
790
findvert (0, x, y, z);
791
memcpy (&data[i * 6], edges[0][x][y][z].data, copysize);
794
findvert (0, x, y, z + 1);
795
memcpy (&data[i * 6], edges[0][x][y][z + 1].data, copysize);
798
findvert (0, x, y + 1, z);
799
memcpy (&data[i * 6], edges[0][x][y + 1][z].data, copysize);
802
findvert (0, x, y + 1, z + 1);
803
memcpy (&data[i * 6], edges[0][x][y + 1][z + 1].data, copysize);
806
findvert (2, x + 1, y, z);
807
memcpy (&data[i * 6], edges[2][x + 1][y][z].data, copysize);
810
findvert (1, x + 1, y, z);
811
memcpy (&data[i * 6], edges[1][x + 1][y][z].data, copysize);
814
findvert (1, x + 1, y, z + 1);
815
memcpy (&data[i * 6], edges[1][x + 1][y][z + 1].data, copysize);
818
findvert (2, x + 1, y + 1, z);
819
memcpy (&data[i * 6], edges[2][x + 1][y + 1][z].data, copysize);
822
surface->addstrip (nedges, data);
823
counter += (nedges + 1);
824
nedges = cubetable[index][counter];
829
// find value at all corners of this cube
830
inline void impCubeVolume::findcornervalues (int x, int y, int z)
832
if (!corners[x][y][z].done) {
833
corners[x][y][z].value = function (corners[x][y][z].position);
834
corners[x][y][z].done = 1;
837
if (!corners[x][y][z].done) {
838
corners[x][y][z].value = function (corners[x][y][z].position);
839
corners[x][y][z].done = 1;
842
if (!corners[x][y][z].done) {
843
corners[x][y][z].value = function (corners[x][y][z].position);
844
corners[x][y][z].done = 1;
847
if (!corners[x][y][z].done) {
848
corners[x][y][z].value = function (corners[x][y][z].position);
849
corners[x][y][z].done = 1;
852
if (!corners[x][y][z].done) {
853
corners[x][y][z].value = function (corners[x][y][z].position);
854
corners[x][y][z].done = 1;
857
if (!corners[x][y][z].done) {
858
corners[x][y][z].value = function (corners[x][y][z].position);
859
corners[x][y][z].done = 1;
862
if (!corners[x][y][z].done) {
863
corners[x][y][z].value = function (corners[x][y][z].position);
864
corners[x][y][z].done = 1;
867
if (!corners[x][y][z].done) {
868
corners[x][y][z].value = function (corners[x][y][z].position);
869
corners[x][y][z].done = 1;
873
inline void impCubeVolume::findvert (int axis, int x, int y, int z)
875
// values used to determine the normal vector
876
static float no, nx, ny, nz;
878
static int copysize = 3 * sizeof (float);
880
if (edges[axis][x][y][z].done)
882
edges[axis][x][y][z].done = 1;
884
// find position of vertex along this edge
887
edges[axis][x][y][z].data[3] = corners[x][y][z].position[0]
888
+ (cubewidth * ((surfacevalue - corners[x][y][z].value)
889
/ (corners[x + 1][y][z].value - corners[x][y][z].value)));
890
edges[axis][x][y][z].data[4] = corners[x][y][z].position[1];
891
edges[axis][x][y][z].data[5] = corners[x][y][z].position[2];
894
edges[axis][x][y][z].data[3] = corners[x][y][z].position[0];
895
edges[axis][x][y][z].data[4] = corners[x][y][z].position[1]
896
+ (cubewidth * ((surfacevalue - corners[x][y][z].value)
897
/ (corners[x][y + 1][z].value - corners[x][y][z].value)));
898
edges[axis][x][y][z].data[5] = corners[x][y][z].position[2];
901
edges[axis][x][y][z].data[3] = corners[x][y][z].position[0];
902
edges[axis][x][y][z].data[4] = corners[x][y][z].position[1];
903
edges[axis][x][y][z].data[5] = corners[x][y][z].position[2]
904
+ (cubewidth * ((surfacevalue - corners[x][y][z].value)
905
/ (corners[x][y][z + 1].value - corners[x][y][z].value)));
908
// find normal vector at vertex along this edge
909
// first find normal vector origin value
910
memcpy (pos, &(edges[axis][x][y][z].data[3]), copysize);
912
// then find values at slight displacements and subtract
914
nx = function (pos) - no;
917
ny = function (pos) - no;
920
nz = function (pos) - no;
922
no = 1.0f / sqrt (nx * nx + ny * ny + nz * nz);
923
edges[axis][x][y][z].data[0] = nx * no;
924
edges[axis][x][y][z].data[1] = ny * no;
925
edges[axis][x][y][z].data[2] = nz * no;