world-wide commit to ruin everything
This commit is contained in:
@@ -2,8 +2,7 @@
|
||||
#include "voxel.h"
|
||||
#include "../lighting/Lightmap.h"
|
||||
|
||||
|
||||
Chunk::Chunk(int xpos, int ypos, int zpos) : x(xpos), y(ypos), z(zpos){
|
||||
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos){
|
||||
voxels = new voxel[CHUNK_VOL];
|
||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||
voxels[i].id = 1;
|
||||
@@ -30,7 +29,7 @@ bool Chunk::isEmpty(){
|
||||
}
|
||||
|
||||
Chunk* Chunk::clone() const {
|
||||
Chunk* other = new Chunk(x,y,z);
|
||||
Chunk* other = new Chunk(x,z);
|
||||
for (int i = 0; i < CHUNK_VOL; i++)
|
||||
other->voxels[i] = voxels[i];
|
||||
other->lightmap->set(lightmap);
|
||||
|
||||
+35
-5
@@ -8,6 +8,12 @@
|
||||
#define CHUNK_D 16
|
||||
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D)
|
||||
|
||||
#define CHUNK_MODIFIED 0x1
|
||||
#define CHUNK_READY 0x2
|
||||
#define CHUNK_LOADED 0x4
|
||||
#define CHUNK_LIGHTED 0x8
|
||||
#define CHUNK_UNSAVED 0x10
|
||||
|
||||
class voxel;
|
||||
class Lightmap;
|
||||
|
||||
@@ -16,19 +22,21 @@ struct RenderData {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#define BIT_ON(f,i) do{f|= i;} while(0)
|
||||
#define BIT_OFF(f,i) do{f&=~(i);} while(0)
|
||||
#define BITSET(f,i,s) if (s) BIT_ON(f,i); else BIT_OFF(f,i);
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
int x,y,z;
|
||||
int x, z;
|
||||
voxel* voxels;
|
||||
Lightmap* lightmap;
|
||||
bool modified = true;
|
||||
bool ready = false;
|
||||
bool loaded = false;
|
||||
int flags = 0;
|
||||
int surrounding = 0;
|
||||
int references = 1;
|
||||
RenderData renderData;
|
||||
|
||||
Chunk(int x, int y, int z);
|
||||
Chunk(int x, int z);
|
||||
~Chunk();
|
||||
|
||||
bool isEmpty();
|
||||
@@ -36,6 +44,28 @@ public:
|
||||
Chunk* clone() const;
|
||||
void incref();
|
||||
void decref();
|
||||
|
||||
// flags getters/setters below
|
||||
|
||||
inline bool isUnsaved() const {return flags & CHUNK_UNSAVED;}
|
||||
|
||||
inline bool isModified() const {return flags & CHUNK_MODIFIED;}
|
||||
|
||||
inline bool isLighted() const {return flags & CHUNK_LIGHTED;}
|
||||
|
||||
inline bool isLoaded() const {return flags & CHUNK_LOADED;}
|
||||
|
||||
inline bool isReady() const {return flags & CHUNK_READY;}
|
||||
|
||||
inline void setUnsaved(bool flag) {BITSET(flags, CHUNK_UNSAVED, flag);}
|
||||
|
||||
inline void setModified(bool flag) {BITSET(flags, CHUNK_MODIFIED, flag);}
|
||||
|
||||
inline void setLoaded(bool flag) {BITSET(flags, CHUNK_LOADED, flag);}
|
||||
|
||||
inline void setLighted(bool flag) {BITSET(flags, CHUNK_LIGHTED, flag);}
|
||||
|
||||
inline void setReady(bool flag) {BITSET(flags, CHUNK_READY, flag);}
|
||||
};
|
||||
|
||||
#endif /* VOXELS_CHUNK_H_ */
|
||||
|
||||
+44
-62
@@ -11,8 +11,8 @@
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
Chunks::Chunks(int w, int h, int d, int ox, int oy, int oz) : w(w), h(h), d(d), ox(ox), oy(oy), oz(oz){
|
||||
volume = w*h*d;
|
||||
Chunks::Chunks(int w, int d, int ox, int oz) : w(w), d(d), ox(ox), oz(oz){
|
||||
volume = w*d;
|
||||
chunks = new Chunk*[volume];
|
||||
chunksSecond = new Chunk*[volume];
|
||||
|
||||
@@ -36,7 +36,6 @@ Chunks::~Chunks(){
|
||||
|
||||
voxel* Chunks::get(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@@ -44,7 +43,7 @@ voxel* Chunks::get(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return nullptr;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@@ -64,7 +63,6 @@ bool Chunks::isObstacle(int x, int y, int z){
|
||||
|
||||
unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@@ -72,7 +70,7 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return 0;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@@ -85,7 +83,6 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
|
||||
unsigned short Chunks::getLight(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@@ -93,7 +90,7 @@ unsigned short Chunks::getLight(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return 0;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@@ -106,7 +103,6 @@ unsigned short Chunks::getLight(int x, int y, int z){
|
||||
|
||||
Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@@ -114,48 +110,44 @@ Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return nullptr;
|
||||
return chunks[(cy * d + cz) * w + cx];
|
||||
}
|
||||
|
||||
Chunk* Chunks::getChunk(int x, int y, int z){
|
||||
Chunk* Chunks::getChunk(int x, int z){
|
||||
x -= ox;
|
||||
y -= oy;
|
||||
z -= oz;
|
||||
if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d)
|
||||
if (x < 0 || z < 0 || x >= w || z >= d)
|
||||
return nullptr;
|
||||
return chunks[(y * d + z) * w + x];
|
||||
return chunks[z * w + x];
|
||||
}
|
||||
|
||||
void Chunks::set(int x, int y, int z, int id){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
if (y < 0 || y >= CHUNK_H)
|
||||
return;
|
||||
int cz = z / CHUNK_D;
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cz < 0 || cx >= w || cz >= d)
|
||||
return;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
Chunk* chunk = chunks[cz * w + cx];
|
||||
if (chunk == nullptr)
|
||||
return;
|
||||
int lx = x - cx * CHUNK_W;
|
||||
int ly = y - cy * CHUNK_H;
|
||||
int lz = z - cz * CHUNK_D;
|
||||
chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx].id = id;
|
||||
chunk->modified = true;
|
||||
chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx].id = id;
|
||||
chunk->setUnsaved(true);
|
||||
chunk->setModified(true);
|
||||
|
||||
if (lx == 0 && (chunk = getChunk(cx+ox-1, cy+oy, cz+oz))) chunk->modified = true;
|
||||
if (ly == 0 && (chunk = getChunk(cx+ox, cy+oy-1, cz+oz))) chunk->modified = true;
|
||||
if (lz == 0 && (chunk = getChunk(cx+ox, cy+oy, cz+oz-1))) chunk->modified = true;
|
||||
if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) chunk->setModified(true);
|
||||
if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) chunk->setModified(true);
|
||||
|
||||
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cy+oy, cz+oz))) chunk->modified = true;
|
||||
if (ly == CHUNK_H-1 && (chunk = getChunk(cx+ox, cy+oy+1, cz+oz))) chunk->modified = true;
|
||||
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cy+oy, cz+oz+1))) chunk->modified = true;
|
||||
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) chunk->setModified(true);
|
||||
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) chunk->setModified(true);
|
||||
}
|
||||
|
||||
voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, vec3& iend) {
|
||||
@@ -246,48 +238,42 @@ voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, v
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Chunks::setCenter(WorldFiles* worldFiles, int x, int y, int z) {
|
||||
void Chunks::setCenter(WorldFiles* worldFiles, int x, int z) {
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
int cz = z / CHUNK_D;
|
||||
cx -= ox;
|
||||
cy -= oy;
|
||||
cz -= oz;
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
cx -= w/2;
|
||||
cy -= h/2;
|
||||
cz -= d/2;
|
||||
if (cx != 0 || cy != 0 || cz != 0)
|
||||
translate(worldFiles, cx,cy,cz);
|
||||
if (cx | cz) {
|
||||
translate(worldFiles, cx,cz);
|
||||
}
|
||||
}
|
||||
|
||||
void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
|
||||
void Chunks::translate(WorldFiles* worldFiles, int dx, int dz){
|
||||
for (unsigned int i = 0; i < volume; i++){
|
||||
chunksSecond[i] = nullptr;
|
||||
meshesSecond[i] = nullptr;
|
||||
}
|
||||
for (unsigned int y = 0; y < h; y++){
|
||||
for (unsigned int z = 0; z < d; z++){
|
||||
for (unsigned int x = 0; x < w; x++){
|
||||
Chunk* chunk = chunks[(y * d + z) * w + x];
|
||||
int nx = x - dx;
|
||||
int ny = y - dy;
|
||||
int nz = z - dz;
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = meshes[(y * d + z) * w + x];
|
||||
if (nx < 0 || ny < 0 || nz < 0 || nx >= w || ny >= h || nz >= d){
|
||||
worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||
chunk->decref();
|
||||
delete mesh;
|
||||
chunksCount--;
|
||||
continue;
|
||||
}
|
||||
meshesSecond[(ny * d + nz) * w + nx] = mesh;
|
||||
chunksSecond[(ny * d + nz) * w + nx] = chunk;
|
||||
for (int z = 0; z < d; z++){
|
||||
for (int x = 0; x < w; x++){
|
||||
Chunk* chunk = chunks[z * w + x];
|
||||
int nx = x - dx;
|
||||
int nz = z - dz;
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = meshes[z * w + x];
|
||||
if (nx < 0 || nz < 0 || nx >= w || nz >= d){
|
||||
worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||
chunk->decref();
|
||||
delete mesh;
|
||||
chunksCount--;
|
||||
continue;
|
||||
}
|
||||
meshesSecond[nz * w + nx] = mesh;
|
||||
chunksSecond[nz * w + nx] = chunk;
|
||||
}
|
||||
}
|
||||
Chunk** ctemp = chunks;
|
||||
@@ -299,26 +285,22 @@ void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
|
||||
meshesSecond = mtemp;
|
||||
|
||||
ox += dx;
|
||||
oy += dy;
|
||||
oz += dz;
|
||||
}
|
||||
|
||||
void Chunks::_setOffset(int x, int y, int z){
|
||||
void Chunks::_setOffset(int x, int z){
|
||||
ox = x;
|
||||
oy = y;
|
||||
oz = z;
|
||||
}
|
||||
|
||||
bool Chunks::putChunk(Chunk* chunk) {
|
||||
int x = chunk->x;
|
||||
int y = chunk->y;
|
||||
int z = chunk->z;
|
||||
x -= ox;
|
||||
y -= oy;
|
||||
z -= oz;
|
||||
if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d)
|
||||
if (x < 0 || z < 0 || x >= w || z >= d)
|
||||
return false;
|
||||
chunks[(y * d + z) * w + x] = chunk;
|
||||
chunks[z * w + x] = chunk;
|
||||
chunksCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
+7
-7
@@ -21,15 +21,15 @@ public:
|
||||
Mesh** meshesSecond;
|
||||
size_t volume;
|
||||
size_t chunksCount;
|
||||
unsigned int w,h,d;
|
||||
int ox,oy,oz;
|
||||
int w,d;
|
||||
int ox,oz;
|
||||
|
||||
Chunks(int w, int h, int d, int ox, int oy, int oz);
|
||||
Chunks(int w, int d, int ox, int oz);
|
||||
~Chunks();
|
||||
|
||||
bool putChunk(Chunk* chunk);
|
||||
|
||||
Chunk* getChunk(int x, int y, int z);
|
||||
Chunk* getChunk(int x, int z);
|
||||
Chunk* getChunkByVoxel(int x, int y, int z);
|
||||
voxel* get(int x, int y, int z);
|
||||
unsigned short getLight(int x, int y, int z);
|
||||
@@ -40,10 +40,10 @@ public:
|
||||
bool isObstacle(int x, int y, int z);
|
||||
|
||||
// does not move chunks inside
|
||||
void _setOffset(int x, int y, int z);
|
||||
void _setOffset(int x, int z);
|
||||
|
||||
void setCenter(WorldFiles* worldFiles, int x, int y, int z);
|
||||
void translate(WorldFiles* worldFiles, int x, int y, int z);
|
||||
void setCenter(WorldFiles* worldFiles, int x, int z);
|
||||
void translate(WorldFiles* worldFiles, int x, int z);
|
||||
|
||||
void clear(bool freeMemory);
|
||||
};
|
||||
|
||||
+144
-116
@@ -48,117 +48,78 @@ int ChunksController::countFreeLoaders(){
|
||||
|
||||
bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
||||
const int w = chunks->w;
|
||||
const int h = chunks->h;
|
||||
const int d = chunks->d;
|
||||
const int ox = chunks->ox;
|
||||
const int oy = chunks->oy;
|
||||
const int oz = chunks->oz;
|
||||
int nearX = 0;
|
||||
int nearY = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = (w/2)*(w/2);
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 2; z < d-2; z++){
|
||||
for (int x = 2; x < w-2; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr){
|
||||
int surrounding = 0;
|
||||
for (int oz = -1; oz <= 1; oz++){
|
||||
for (int ox = -1; ox <= 1; ox++){
|
||||
Chunk* other = chunks->getChunk(chunk->x+ox, chunk->y, chunk->z+oz);
|
||||
if (other != nullptr && other->ready) surrounding++;
|
||||
}
|
||||
for (int z = 2; z < d-2; z++){
|
||||
for (int x = 2; x < w-2; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr){
|
||||
int surrounding = 0;
|
||||
for (int oz = -1; oz <= 1; oz++){
|
||||
for (int ox = -1; ox <= 1; ox++){
|
||||
Chunk* other = chunks->getChunk(chunk->x+ox, chunk->z+oz);
|
||||
if (other != nullptr && other->isReady()) surrounding++;
|
||||
}
|
||||
chunk->surrounding = surrounding;
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int ly = y - h / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + ly * ly + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearY = y;
|
||||
nearZ = z;
|
||||
}
|
||||
chunk->surrounding = surrounding;
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int index = (nearY * d + nearZ) * w + nearX;
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr)
|
||||
return false;
|
||||
|
||||
ChunksLoader* freeLoader = nullptr;
|
||||
for (int i = 0; i < loadersCount; i++){
|
||||
ChunksLoader* loader = loaders[i];
|
||||
if (loader->isBusy()){
|
||||
continue;
|
||||
}
|
||||
freeLoader = loader;
|
||||
break;
|
||||
}
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return false;
|
||||
chunk = new Chunk(nearX+ox,nearY+oy,nearZ+oz);
|
||||
|
||||
chunk = new Chunk(nearX+ox, nearZ+oz);
|
||||
if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels))
|
||||
chunk->loaded = true;
|
||||
chunk->setLoaded(true);
|
||||
|
||||
chunks->putChunk(chunk);
|
||||
|
||||
Chunk* closes[27];
|
||||
for (int i = 0; i < 27; i++)
|
||||
Chunk* closes[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
if (!other->ready)
|
||||
if (!other->isReady())
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oy = other->y - chunk->y;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
|
||||
if (abs(ox) > 1 || abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oy += 1;
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
freeLoader->load(chunk, (Chunk**)closes);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
const int w = chunks->w;
|
||||
const int h = chunks->h;
|
||||
const int d = chunks->d;
|
||||
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->renderData.vertices > (void*)1){
|
||||
const int chunk_attrs[] = {3,2,4, 0};
|
||||
Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs);
|
||||
if (chunks->meshes[index])
|
||||
delete chunks->meshes[index];
|
||||
chunks->meshes[index] = mesh;
|
||||
delete[] chunk->renderData.vertices;
|
||||
chunk->renderData.vertices = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChunksLoader* ChunksController::getFreeLoader() {
|
||||
ChunksLoader* freeLoader = nullptr;
|
||||
for (int i = 0; i < loadersCount; i++){
|
||||
ChunksLoader* loader = loaders[i];
|
||||
@@ -168,85 +129,152 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
freeLoader = loader;
|
||||
break;
|
||||
}
|
||||
return freeLoader;
|
||||
}
|
||||
|
||||
void ChunksController::calculateLights() {
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return;
|
||||
const int w = chunks->w;
|
||||
const int d = chunks->d;
|
||||
int nearX = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = INT_MAX;
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
return;
|
||||
Chunk* closes[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1|| abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oz += 1;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
freeLoader->lights(chunk, (Chunk**)closes);
|
||||
}
|
||||
|
||||
bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
const int w = chunks->w;
|
||||
const int d = chunks->d;
|
||||
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->renderData.vertices > (void*)1){
|
||||
const int chunk_attrs[] = {3,2,4, 0};
|
||||
Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs);
|
||||
if (chunks->meshes[index])
|
||||
delete chunks->meshes[index];
|
||||
chunks->meshes[index] = mesh;
|
||||
delete[] chunk->renderData.vertices;
|
||||
chunk->renderData.vertices = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return false;
|
||||
|
||||
int nearX = 0;
|
||||
int nearY = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = INT_MAX;
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh != nullptr && !chunk->modified)
|
||||
continue;
|
||||
if (!chunk->ready || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int ly = y - h / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + ly * ly + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearY = y;
|
||||
nearZ = z;
|
||||
}
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh != nullptr && !chunk->isModified())
|
||||
continue;
|
||||
if (!chunk->isReady() || !chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int index = (nearY * d + nearZ) * w + nearX;
|
||||
|
||||
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr){
|
||||
return false;
|
||||
}
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh == nullptr || chunk->modified){
|
||||
Chunk* closes[27];
|
||||
if (mesh == nullptr || chunk->isModified()){
|
||||
if (chunk->renderData.vertices != nullptr) {
|
||||
return false;
|
||||
}
|
||||
Chunk* closes[9];
|
||||
if (chunk->isEmpty()){
|
||||
chunks->meshes[index] = nullptr;
|
||||
return false;
|
||||
}
|
||||
chunk->modified = false;
|
||||
for (int i = 0; i < 27; i++)
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
if (!other->ready)
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oy = other->y - chunk->y;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
|
||||
if (abs(ox) > 1 || abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oy += 1;
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
if ((!other->isReady() || !other->isLighted()) && other != chunk)
|
||||
return false;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
if (chunk->renderData.vertices == nullptr){
|
||||
chunk->renderData.vertices = (float*)1;
|
||||
freeLoader->render(chunk, (Chunk**)closes);
|
||||
|
||||
return true;
|
||||
}
|
||||
//mesh = renderer->render(chunk, (const Chunk**)closes);
|
||||
//chunks->meshes[index] = mesh;
|
||||
chunk->setModified(false);
|
||||
chunk->renderData.vertices = (float*)1;
|
||||
freeLoader->render(chunk, (Chunk**)closes);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ public:
|
||||
ChunksController(World* world, Chunks* chunks, Lighting* lighting);
|
||||
~ChunksController();
|
||||
|
||||
ChunksLoader* getFreeLoader();
|
||||
int countFreeLoaders();
|
||||
bool loadVisible(WorldFiles* worldFiles);
|
||||
void calculateLights();
|
||||
bool _buildMeshes(VoxelRenderer* renderer, int tick);
|
||||
};
|
||||
|
||||
|
||||
+30
-19
@@ -12,10 +12,10 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define CLOSES_C 27
|
||||
#define SURROUNDINGS_C 9
|
||||
|
||||
void ChunksLoader::_thread(){
|
||||
Chunks chunks(3,3,3, -1,-1,-1);
|
||||
Chunks chunks(3, 3, -1, -1);
|
||||
Lighting lighting(&chunks);
|
||||
VoxelRenderer renderer;
|
||||
while (state != OFF){
|
||||
@@ -24,9 +24,9 @@ void ChunksLoader::_thread(){
|
||||
continue;
|
||||
}
|
||||
Chunk* chunk = current;
|
||||
chunks._setOffset(chunk->x-1, chunk->y-1, chunk->z-1);
|
||||
for (size_t i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes[i];
|
||||
chunks._setOffset(chunk->x-1, chunk->z-1);
|
||||
for (size_t i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings[i];
|
||||
if (other){
|
||||
chunks.putChunk(other);
|
||||
}
|
||||
@@ -34,8 +34,9 @@ void ChunksLoader::_thread(){
|
||||
|
||||
if (state == LOAD){
|
||||
chunks.putChunk(chunk);
|
||||
if (!chunk->loaded){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed);
|
||||
if (!chunk->isLoaded()){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->z, world->seed);
|
||||
chunk->setUnsaved(true);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < CHUNK_VOL; i++){
|
||||
@@ -44,11 +45,17 @@ void ChunksLoader::_thread(){
|
||||
chunk->voxels[i].id = 11;
|
||||
}
|
||||
}
|
||||
lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
|
||||
lighting.prebuildSkyLight(chunk->x, chunk->z);
|
||||
}
|
||||
else if (state == LIGHTS) {
|
||||
lighting.buildSkyLight(chunk->x, chunk->z);
|
||||
lighting.onChunkLoaded(chunk->x, chunk->z);
|
||||
chunk->setLighted(true);
|
||||
}
|
||||
else if (state == RENDER){
|
||||
chunk->setModified(false);
|
||||
size_t size;
|
||||
renderer.render(chunk, (const Chunk**)(closes.load()), size);
|
||||
renderer.render(chunk, (const Chunk**)(surroundings.load()), size);
|
||||
float* vertices = new float[size];
|
||||
for (size_t i = 0; i < size; i++)
|
||||
vertices[i] = renderer.buffer[i];
|
||||
@@ -57,33 +64,33 @@ void ChunksLoader::_thread(){
|
||||
}
|
||||
|
||||
chunks.clear(false);
|
||||
for (int i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes[i];
|
||||
for (int i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings[i];
|
||||
if (other)
|
||||
other->decref();
|
||||
}
|
||||
chunk->ready = true;
|
||||
chunk->setReady(true);
|
||||
current = nullptr;
|
||||
chunk->decref();
|
||||
}
|
||||
}
|
||||
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode){
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** surroundings_passed, LoaderMode mode){
|
||||
if (isBusy()){
|
||||
std::cerr << "performing while busy" << std::endl;
|
||||
return;
|
||||
}
|
||||
chunk->incref();
|
||||
if (closes == nullptr){
|
||||
closes = new Chunk*[CLOSES_C];
|
||||
if (surroundings == nullptr){
|
||||
surroundings = new Chunk*[SURROUNDINGS_C];
|
||||
}
|
||||
for (int i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes_passed[i];
|
||||
for (int i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings_passed[i];
|
||||
if (other == nullptr)
|
||||
closes[i] = nullptr;
|
||||
surroundings[i] = nullptr;
|
||||
else {
|
||||
other->incref();
|
||||
closes[i] = other;
|
||||
surroundings[i] = other;
|
||||
}
|
||||
}
|
||||
current = chunk;
|
||||
@@ -94,6 +101,10 @@ void ChunksLoader::load(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, LOAD);
|
||||
}
|
||||
|
||||
void ChunksLoader::lights(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, LIGHTS);
|
||||
}
|
||||
|
||||
void ChunksLoader::render(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, RENDER);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class Chunk;
|
||||
class World;
|
||||
|
||||
enum LoaderMode {
|
||||
OFF, IDLE, LOAD, RENDER,
|
||||
OFF, IDLE, LOAD, LIGHTS, RENDER,
|
||||
};
|
||||
|
||||
class ChunksLoader final {
|
||||
@@ -22,7 +22,7 @@ private:
|
||||
std::thread loaderThread;
|
||||
void _thread();
|
||||
std::atomic<Chunk*> current {nullptr};
|
||||
std::atomic<Chunk**> closes {nullptr};
|
||||
std::atomic<Chunk**> surroundings {nullptr};
|
||||
std::atomic<LoaderMode> state {IDLE};
|
||||
World* world;
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
}
|
||||
|
||||
void load(Chunk* chunk, Chunk** closes_passed);
|
||||
void lights(Chunk* chunk, Chunk** closes_passed);
|
||||
void render(Chunk* chunk, Chunk** closes_passed);
|
||||
|
||||
void stop(){
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "voxel.h"
|
||||
#include "Chunk.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/noise.hpp>
|
||||
@@ -9,6 +10,8 @@
|
||||
#include "../maths/FastNoiseLite.h"
|
||||
#include <time.h>
|
||||
|
||||
#include "../declarations.h"
|
||||
|
||||
class PseudoRandom {
|
||||
unsigned short seed;
|
||||
public:
|
||||
@@ -64,7 +67,7 @@ float calc_height_faster(fnl_state *noise, int real_x, int real_z){
|
||||
height *= 64.0f;
|
||||
return height;
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, int real_x, int real_y, int real_z, int tileSize){
|
||||
const int tileX = floor((double)real_x/(double)tileSize);
|
||||
const int tileY = floor((double)real_z/(double)tileSize);
|
||||
@@ -92,18 +95,14 @@ int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
|
||||
fnl_state noise = fnlCreateState();
|
||||
noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
|
||||
noise.seed = seed * 60617077 % 25896307;
|
||||
|
||||
PseudoRandom randomtree;
|
||||
// PseudoRandom random;
|
||||
|
||||
float heights[CHUNK_VOL];
|
||||
|
||||
// std::cout << calc_height(&noise, cx, cy) << "\n";
|
||||
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
int real_x = x + cx * CHUNK_W;
|
||||
@@ -120,14 +119,14 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
float height = heights[z*CHUNK_W+x];
|
||||
|
||||
for (int y = 0; y < CHUNK_H; y++){
|
||||
int real_y = y + cy * CHUNK_H;
|
||||
int id = real_y < 55 ? 9 : 0;
|
||||
if ((real_y == (int)height) && (54 < real_y))
|
||||
id = 2;
|
||||
else if (real_y < (height - 6)){
|
||||
id = 8;
|
||||
int real_y = y;
|
||||
int id = real_y < 55 ? BLOCK_WATER : BLOCK_AIR;
|
||||
if ((real_y == (int)height) && (54 < real_y)) {
|
||||
id = BLOCK_GRASS_BLOCK;
|
||||
} else if (real_y < (height - 6)){
|
||||
id = BLOCK_STONE;
|
||||
} else if (real_y < height){
|
||||
id = 1;
|
||||
id = BLOCK_DIRT;
|
||||
} else {
|
||||
int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 16);
|
||||
if (tree) {
|
||||
@@ -139,15 +138,15 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
}
|
||||
}
|
||||
if ( ((height - (1.5 - 0.2 * pow(height - 54, 4))) < real_y) && (real_y < height)){
|
||||
id = 10;
|
||||
id = BLOCK_SAND;
|
||||
}
|
||||
if (real_y <= 2)
|
||||
id = 11;
|
||||
id = BLOCK_BEDROCK;
|
||||
if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){
|
||||
id = 12;
|
||||
id = BLOCK_GRASS;
|
||||
}
|
||||
if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){
|
||||
id = 13;
|
||||
id = BLOCK_FLOWER;
|
||||
}
|
||||
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ class voxel;
|
||||
|
||||
class WorldGenerator {
|
||||
public:
|
||||
static void generate(voxel* voxels, int x, int y, int z, int seed);
|
||||
static void generate(voxel* voxels, int x, int z, int seed);
|
||||
};
|
||||
|
||||
#endif /* VOXELS_WORLDGENERATOR_H_ */
|
||||
|
||||
Reference in New Issue
Block a user