chunkmanager: only calculate update sphere indices at startup

vertex-deduplication
EmaMaker 2023-03-25 16:31:47 +01:00
parent 8584d2e974
commit da6608c66a
3 changed files with 61 additions and 68 deletions

View File

@ -16,6 +16,7 @@ namespace chunkmanager
void mesh(); void mesh();
void generate(); void generate();
void init();
void blockpick(bool place); void blockpick(bool place);
uint32_t calculateIndex(uint16_t i, uint16_t j, uint16_t k); uint32_t calculateIndex(uint16_t i, uint16_t j, uint16_t k);

View File

@ -10,6 +10,7 @@
#include <atomic> #include <atomic>
#include <iostream> #include <iostream>
#include <math.h>
#include <mutex> #include <mutex>
#include <set> #include <set>
#include <string> #include <string>
@ -18,6 +19,9 @@
std::unordered_map<std::uint32_t, Chunk::Chunk *> chunks; std::unordered_map<std::uint32_t, Chunk::Chunk *> chunks;
constexpr int chunks_volume = static_cast<int>(1.333333333333*M_PI*(RENDER_DISTANCE*RENDER_DISTANCE*RENDER_DISTANCE));
std::array<std::array<int, 3>, chunks_volume> chunks_indices;
namespace chunkmanager namespace chunkmanager
{ {
// thread management // thread management
@ -92,17 +96,50 @@ namespace chunkmanager
return gen_thread; return gen_thread;
} }
void stopGenThread(){ void init(){
generate_should_run = false; int index{0};
}
void stopMeshThread(){ int xp{0}, x{0};
mesh_should_run = false; bool b = true;
// Iterate over all chunks, in concentric spheres starting fron the player and going
// outwards. Alternate left and right
// Eq. of the sphere (x - a)² + (y - b)² + (z - c)² = r²
while (xp <= RENDER_DISTANCE)
{
// Alternate between left and right
if (b) x = +xp;
else x = -xp;
// Step 1. At current x, get the corresponding y values (2nd degree equation, up to 2
// possible results)
int y1 = static_cast<int>(sqrt((rr) - x*x));
for (int y = -y1 + 1 ; y <= y1; y++)
{
// Step 2. At both y's, get the corresponding z values
int z1 = static_cast<int>(sqrt( rr - x*x - y*y));
for (int z = -z1 + 1; z <= z1; z++){
chunks_indices[index][0] = x;
chunks_indices[index][1] = y;
chunks_indices[index][2] = z;
std::cout << index << "/" << chunks_volume << "\n";
index++;
}
}
if (!b)
{
xp++;
b = true;
}
else b = false;
}
} }
void update(float deltaTime) void update(float deltaTime)
{ {
// Try to lock resources // Try to lock resources
f = 0; f = 0;
f |= mutex_queue_generate.try_lock(); f |= mutex_queue_generate.try_lock();
@ -143,69 +180,14 @@ namespace chunkmanager
to_delete_delete.clear(); to_delete_delete.clear();
if(nUnloaded) std::cout << "Unloaded " << nUnloaded << " chunks\n"; if(nUnloaded) std::cout << "Unloaded " << nUnloaded << " chunks\n";
// Iterate over all chunks, in concentric spheres starting fron the player and going for(int i = 0; i < chunks_volume; i++)
// outwards. Alternate left and right updateChunk(calculateIndex(chunks_indices[i][0] + chunkX,
// Eq. of the sphere (x - a)² + (y - b)² + (z - c)² = r² chunks_indices[i][1] + chunkY,
chunks_indices[i][2] + chunkZ),
chunks_indices[i][0] + chunkX,
chunks_indices[i][1] + chunkY,
chunks_indices[i][2] + chunkZ);
// Possible change: coordinates everything at the origin, then translate later?
// Step 1. Eq. of a circle. Fix the x coordinate, get the 2 possible y's
int xp{0}, x{0};
bool b = true;
while (xp <= RENDER_DISTANCE)
{
// Alternate between left and right
if (b) x = chunkX + xp;
else x = chunkX - xp;
// Possible optimization: use sqrt lookup
int y1 = sqrt((rr) - (x - chunkX) * (x - chunkX)) + chunkY;
int y2 = -sqrt((rr) - (x - chunkX) * (x - chunkX)) + chunkY;
for (int y = y2 + 1; y <= y1; y++)
{
// Step 2. At both y's, get the corresponding z values
int z1 = sqrt((rr) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ;
int z2 = -sqrt((rr) - (x - chunkX) * (x - chunkX) - (y - chunkY) * (y - chunkY)) + chunkZ;
// std::cout << "RENDER DISTANCE " << RENDER_DISTANCE << " Current radius: " << r << " X: " << x << " Y Limits: " << y1 << " - " << y2 << "(" << y << ") Z Limits: " << z1 << " - " << z2 << std::endl;
for (int z = z2; z <= z1; z++)
{
uint16_t i{}, j{}, k{};
if (x < 0)
i = 0;
else if (x >= 1024)
i = 1023;
else
i = x;
if (y < 0)
j = 0;
else if (y >= 1024)
j = 1023;
else
j = y;
if (z < 0)
k = 0;
else if (z >= 1024)
k = 1023;
else
k = z;
uint32_t in = calculateIndex(i, j, k);
chunkmanager::updateChunk(in, i, j, k);
}
}
if (!b)
{
xp++;
b = true;
}
else b = false;
}
//std::cout << "Chunks to mesh: " << to_mesh.size() << "\n"; //std::cout << "Chunks to mesh: " << to_mesh.size() << "\n";
//std::cout << "Chunks to generate: " << to_generate.size() << "\n"; //std::cout << "Chunks to generate: " << to_generate.size() << "\n";
//std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n"; //std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
@ -366,4 +348,13 @@ namespace chunkmanager
for (auto &n : chunks) for (auto &n : chunks)
delete n.second; delete n.second;
} }
void stopGenThread(){
generate_should_run = false;
}
void stopMeshThread(){
mesh_should_run = false;
}
}; };

View File

@ -59,6 +59,7 @@ int main()
std::cout << "Using GPU: " << glGetString(GL_VENDOR) << " " << glGetString(GL_RENDERER) << "\n"; std::cout << "Using GPU: " << glGetString(GL_VENDOR) << " " << glGetString(GL_RENDERER) << "\n";
SpaceFilling::initLUT(); SpaceFilling::initLUT();
chunkmanager::init();
std::thread genThread = chunkmanager::initGenThread(); std::thread genThread = chunkmanager::initGenThread();
std::thread meshThread = chunkmanager::initMeshThread(); std::thread meshThread = chunkmanager::initMeshThread();