60 void PXHelper(
VoxelGrid *s,
int x,
int y,
int ymax,
int z,
int zmax, std::vector<triangle> &data);
62 void NXHelper(
VoxelGrid *s,
int x,
int y,
int ymax,
int z,
int zmax, std::vector<triangle> &data);
64 void PYHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int z,
int zmax, std::vector<triangle> &data);
66 void NYHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int z,
int zmax, std::vector<triangle> &data);
68 void PZHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int ymax,
int z, std::vector<triangle> &data);
70 void NZHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int ymax,
int z, std::vector<triangle> &data);
77 std::vector<std::thread> threads;
78 int numThreads = std::thread::hardware_concurrency();
80 for (
int x = 0; x < numThreads; x++)
82 threads.push_back(std::thread(
ThreadedWorker, s, std::ref(data), std::ref(queue), std::ref(lock)));
87 for (
int a = 0; a < x; a++)
92 for (
int b = 0; b < y; b++)
97 for (
int c = 0; c < z; c++)
103 for (
int x = 0; x < numThreads; x++)
104 queue.
WaitAdd({xPositive, -1});
105 for (
int x = 0; x < numThreads; x++)
133 std::vector<triangle> localData;
151 if (localData.size() > 0)
154 data.insert(data.end(), localData.begin(), localData.end());
161 if (y >= ymax || z >= zmax)
169 if (y+count >= ymax || z+count >= zmax)
172 for (
int t = 0; t <= count; t++)
174 for (
int t = 0; t <= count; t++)
176 if ((valid && tmp == (count+1)*2) || (!valid && tmp == 0))
188 std::pair<int, int>
XMaxRect(
VoxelGrid *s,
int x,
int y,
int ymax,
int z,
int zmax,
int xOffset)
190 int minLen =
XMaxSquare(s, x, y, ymax, z, zmax, xOffset);
192 return {minLen, minLen};
198 if (y+minLen+yCount >= ymax)
204 for (
int t = 0; t < minLen; t++)
205 tmp += (s->
IsBlocked(x, y+minLen+yCount, z+t) && !s->
IsBlocked(x+xOffset, y+minLen+yCount, z+t))?1:0;
218 if (z+minLen+zCount >= zmax)
224 for (
int t = 0; t < minLen; t++)
225 tmp += (s->
IsBlocked(x, y+t, z+minLen+zCount) && !s->
IsBlocked(x+xOffset, y+t, z+minLen+zCount))?1:0;
238 return {minLen, minLen+zCount};
239 return {minLen+yCount, minLen};
243 void PXHelper(
VoxelGrid *s,
int x,
int y,
int ymax,
int z,
int zmax, std::vector<triangle> &data)
246 auto v =
XMaxRect(s, x, y, ymax, z, zmax, 1);
248 int zSize = v.second;
251 data.push_back(
MakeTriangle({1, 0, 0}, {x+1, y, z}, {x+1, y+ySize, z}, {x+1, y+ySize, z+zSize}));
252 data.push_back(
MakeTriangle({1, 0, 0}, {x+1, y, z}, {x+1, y+ySize, z+zSize}, {x+1, y, z+zSize}));
254 else if (ySize < 0) {
258 else if (ySize == 0){
262 PXHelper(s, x, y+ySize, ymax, z, z+zSize, data);
263 PXHelper(s, x, y, y+ySize, z+zSize, zmax, data);
264 PXHelper(s, x, y+ySize, ymax, z+zSize, zmax, data);
275 void NXHelper(
VoxelGrid *s,
int x,
int y,
int ymax,
int z,
int zmax, std::vector<triangle> &data)
278 auto v =
XMaxRect(s, x, y, ymax, z, zmax, -1);
280 int zSize = v.second;
283 data.push_back(
MakeTriangle({-1, 0, 0}, {x, y, z}, {x, y+ySize, z+zSize}, {x, y+ySize, z}));
284 data.push_back(
MakeTriangle({-1, 0, 0}, {x, y, z}, {x, y, z+zSize}, {x, y+ySize, z+zSize}));
286 else if (ySize < 0) {
290 else if (ySize == 0){
294 NXHelper(s, x, y+ySize, ymax, z, z+zSize, data);
295 NXHelper(s, x, y, y+ySize, z+zSize, zmax, data);
296 NXHelper(s, x, y+ySize, ymax, z+zSize, zmax, data);
308 if (x >= xmax || z >= zmax)
316 if (x+count >= xmax || z+count >= zmax)
319 for (
int t = 0; t <= count; t++)
321 for (
int t = 0; t <= count; t++)
323 if ((valid && tmp == (count+1)*2) || (!valid && tmp == 0))
335 std::pair<int, int>
YMaxRect(
VoxelGrid *s,
int x,
int xmax,
int y,
int z,
int zmax,
int yOffset)
337 int minLen =
YMaxSquare(s, x, xmax, y, z, zmax, yOffset);
339 return {minLen, minLen};
345 if (x+minLen+xCount >= xmax)
351 for (
int t = 0; t < minLen; t++)
352 tmp += (s->
IsBlocked(x+minLen+xCount, y, z+t) && !s->
IsBlocked(x+minLen+xCount, y+yOffset, z+t))?1:0;
365 if (z+minLen+zCount >= zmax)
371 for (
int t = 0; t < minLen; t++)
372 tmp += (s->
IsBlocked(x+t, y, z+minLen+zCount) && !s->
IsBlocked(x+t, y+yOffset, z+minLen+zCount))?1:0;
385 return {minLen, minLen+zCount};
386 return {minLen+xCount, minLen};
389 void PYHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int z,
int zmax, std::vector<triangle> &data)
391 auto v =
YMaxRect(s, x, xmax, y, z, zmax, 1);
393 int zSize = v.second;
397 data.push_back(
MakeTriangle({0, 1, 0}, {x, y+1, z}, {x+xSize, y+1, z+zSize}, {x+xSize, y+1, z}));
398 data.push_back(
MakeTriangle({0, 1, 0}, {x, y+1, z}, {x, y+1, z+zSize}, {x+xSize, y+1, z+zSize}));
400 else if (xSize < 0) {
404 else if (xSize == 0){
408 PYHelper(s, x+xSize, xmax, y, z, z+zSize, data);
409 PYHelper(s, x, x+xSize, y, z+zSize, zmax, data);
410 PYHelper(s, x+xSize, xmax, y, z+zSize, zmax, data);
420 void NYHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int z,
int zmax, std::vector<triangle> &data)
422 auto v =
YMaxRect(s, x, xmax, y, z, zmax, -1);
424 int zSize = v.second;
428 data.push_back(
MakeTriangle({0, -1, 0}, {x, y, z}, {x+xSize, y, z}, {x+xSize, y, z+zSize}));
429 data.push_back(
MakeTriangle({0, -1, 0}, {x, y, z}, {x+xSize, y, z+zSize}, {x, y, z+zSize}));
431 else if (xSize < 0) {
435 else if (xSize == 0){
439 NYHelper(s, x+xSize, xmax, y, z, z+zSize, data);
440 NYHelper(s, x, x+xSize, y, z+zSize, zmax, data);
441 NYHelper(s, x+xSize, xmax, y, z+zSize, zmax, data);
453 if (x >= xmax || y >= ymax)
461 if (x+count >= xmax || y+count >= ymax)
464 for (
int t = 0; t <= count; t++)
466 for (
int t = 0; t <= count; t++)
468 if ((valid && tmp == (count+1)*2) || (!valid && tmp == 0))
480 std::pair<int, int>
ZMaxRect(
VoxelGrid *s,
int x,
int xmax,
int y,
int ymax,
int z,
int zOffset)
482 int minLen =
ZMaxSquare(s, x, xmax, y, ymax, z, zOffset);
484 return {minLen, minLen};
490 if (x+minLen+xCount >= xmax)
496 for (
int t = 0; t < minLen; t++)
497 tmp += (s->
IsBlocked(x+minLen+xCount, y+t, z) && !s->
IsBlocked(x+minLen+xCount, y+t, z+zOffset))?1:0;
510 if (y+minLen+yCount >= ymax)
516 for (
int t = 0; t < minLen; t++)
517 tmp += (s->
IsBlocked(x+t, y+minLen+yCount, z) && !s->
IsBlocked(x+t, y+minLen+yCount, z+zOffset))?1:0;
530 return {minLen, minLen+yCount};
531 return {minLen+xCount, minLen};
534 void PZHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int ymax,
int z, std::vector<triangle> &data)
536 auto v =
ZMaxRect(s, x, xmax, y, ymax, z, 1);
538 int ySize = v.second;
542 data.push_back(
MakeTriangle({0, 0, 1}, {x, y, z+1}, {x+xSize, y, z+1}, {x+xSize, y+ySize, z+1}));
543 data.push_back(
MakeTriangle({0, 0, 1}, {x, y, z+1}, {x+xSize, y+ySize, z+1}, {x, y+ySize, z+1}));
545 else if (xSize < 0) {
549 else if (xSize == 0){
553 PZHelper(s, x+xSize, xmax, y, y+ySize, z, data);
554 PZHelper(s, x, x+xSize, y+ySize, ymax, z, data);
555 PZHelper(s, x+xSize, xmax, y+ySize, ymax, z, data);
565 void NZHelper(
VoxelGrid *s,
int x,
int xmax,
int y,
int ymax,
int z, std::vector<triangle> &data)
567 auto v =
ZMaxRect(s, x, xmax, y, ymax, z, -1);
570 int ySize = v.second;
574 data.push_back(
MakeTriangle({0, 0, -1}, {x, y, z}, {x+xSize, y+ySize, z}, {x+xSize, y, z}));
575 data.push_back(
MakeTriangle({0, 0, -1}, {x, y, z}, {x, y+ySize, z}, {x+xSize, y+ySize, z}));
577 else if (xSize < 0) {
581 else if (xSize == 0){
585 NZHelper(s, x+xSize, xmax, y, y+ySize, z, data);
586 NZHelper(s, x, x+xSize, y+ySize, ymax, z, data);
587 NZHelper(s, x+xSize, xmax, y+ySize, ymax, z, data);