forked from webaverse/physics-wasm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflod.cc
141 lines (131 loc) · 5.5 KB
/
flod.cc
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
#include "flod.h"
#include "util.h"
#include <memory>
// #include <iostream>
inline void _floodFill(int x, int y, int z, int startFace, float *ether, int minX, int maxX, int minY, int maxY, int minZ, int maxZ, unsigned char *peeks, unsigned char *seenPeeks) {
std::unique_ptr<int[]> queue(new int[NUM_CELLS_OVERSCAN * NUM_CELLS_OVERSCAN * NUM_CELLS_OVERSCAN * 4]);
unsigned int queueEnd = 0;
const int index = getEtherIndex(x, y, z);
queue[queueEnd * 4 + 0] = x;
queue[queueEnd * 4 + 1] = y;
queue[queueEnd * 4 + 2] = z;
queue[queueEnd * 4 + 3] = index;
queueEnd++;
seenPeeks[index] = 1;
for (unsigned int queueStart = 0; queueStart < queueEnd; queueStart++) {
const int x = queue[queueStart * 4 + 0];
const int y = queue[queueStart * 4 + 1];
const int z = queue[queueStart * 4 + 2];
const int index = queue[queueStart * 4 + 3];
if (ether[index] >= 0) { // if empty space
if (z == minZ && startFace != (int)PEEK_FACES::BACK) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::BACK]] = 1;
}
if (z == maxZ && startFace != (int)PEEK_FACES::FRONT) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::FRONT]] = 1;
}
if (x == minX && startFace != (int)PEEK_FACES::LEFT) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::LEFT]] = 1;
}
if (x == maxX && startFace != (int)PEEK_FACES::RIGHT) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::RIGHT]] = 1;
}
if (y == maxY && startFace != (int)PEEK_FACES::TOP) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::TOP]] = 1;
}
if (y == minY && startFace != (int)PEEK_FACES::BOTTOM) {
peeks[PEEK_FACE_INDICES[startFace << 3 | (int)PEEK_FACES::BOTTOM]] = 1;
}
for (int dx = -1; dx <= 1; dx++) {
const int ax = x + dx;
if (ax >= minX && ax <= maxX) {
for (int dz = -1; dz <= 1; dz++) {
const int az = z + dz;
if (az >= minZ && az <= maxZ) {
for (int dy = -1; dy <= 1; dy++) {
const int ay = y + dy;
if (ay >= minY && ay <= maxY) {
const int index = getEtherIndex(ax, ay, az);
if (!seenPeeks[index]) {
queue[queueEnd * 4 + 0] = ax;
queue[queueEnd * 4 + 1] = ay;
queue[queueEnd * 4 + 2] = az;
queue[queueEnd * 4 + 3] = index;
queueEnd++;
seenPeeks[index] = 1;
}
}
}
}
}
}
}
}
}
}
void flod(float *ether, int *shift, unsigned char *peeks) {
const int minX = shift[0] + 0;
const int maxX = shift[0] + NUM_CELLS;
const int minY = shift[1] + 0;
const int maxY = shift[1] + NUM_CELLS;
const int minZ = shift[2] + 0;
const int maxZ = shift[2] + NUM_CELLS;
// std::cout << "limits " << minX << ":" << maxX << ":" << minY << ":" << maxY << ":" << minZ << ":" << maxZ << "\n";
// const geometry = geometries[i];
// const peeks = new Uint8Array(16);
unsigned char seenPeeks[NUM_CELLS_OVERSCAN * (NUM_CELLS_HEIGHT + 1) * NUM_CELLS_OVERSCAN];
// const minY = i * NUM_CELLS;
// const maxY = (i + 1) * NUM_CELLS;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
_floodFill(x, y, maxZ, (int)PEEK_FACES::FRONT, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
_floodFill(x, y, minZ, (int)PEEK_FACES::BACK, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int z = minZ; z <= maxZ; z++) {
for (int y = minY; y <= maxY; y++) {
_floodFill(minX, y, z, (int)PEEK_FACES::LEFT, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int z = minZ; z <= maxZ; z++) {
for (int y = minY; y <= maxY; y++) {
_floodFill(maxX, y, z, (int)PEEK_FACES::RIGHT, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
_floodFill(x, maxY, z, (int)PEEK_FACES::TOP, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
_floodFill(x, minY, z, (int)PEEK_FACES::BOTTOM, ether, minX, maxX, minY, maxY, minZ, maxZ, peeks, seenPeeks);
}
}
for (int startFace = 0; startFace < 6; startFace++) {
for (int endFace = 0; endFace < 6; endFace++) {
if (endFace != startFace) {
if (peeks[PEEK_FACE_INDICES[startFace << 3 | endFace]] == 1) {
peeks[PEEK_FACE_INDICES[endFace << 3 | startFace]] = 1;
for (int crossFace = 0; crossFace < 6; crossFace++) {
if (crossFace != startFace && crossFace != endFace) {
if (peeks[PEEK_FACE_INDICES[startFace << 3 | crossFace]] == 1) {
peeks[PEEK_FACE_INDICES[crossFace << 3 | startFace]] = 1;
peeks[PEEK_FACE_INDICES[crossFace << 3 | endFace]] = 1;
peeks[PEEK_FACE_INDICES[endFace << 3 | crossFace]] = 1;
} else if (peeks[PEEK_FACE_INDICES[endFace << 3 | crossFace]] == 1) {
peeks[PEEK_FACE_INDICES[crossFace << 3 | startFace]] = 1;
peeks[PEEK_FACE_INDICES[crossFace << 3 | endFace]] = 1;
peeks[PEEK_FACE_INDICES[startFace << 3 | crossFace]] = 1;
}
}
}
}
}
}
}
}