Browse Source

cuckoo hash map

testing
totallyfake 1 year ago
parent
commit
32c0172d08
15 changed files with 336 additions and 90 deletions
  1. 3
    0
      .gitmodules
  2. 2
    1
      CMakeLists.txt
  3. 2
    2
      include/chunk.h
  4. 6
    1
      include/voxelinfo.h
  5. 14
    1
      include/voxelutils.h
  6. 3
    1
      include/world.h
  7. 1
    0
      libcuckoo
  8. 19
    17
      res/shaders/voxelvert.vert.glsl
  9. 218
    0
      src/2
  10. 5
    3
      src/chunk.cpp
  11. 6
    2
      src/graphics/chunkmesh.cpp
  12. 6
    30
      src/scenes/testscene.cpp
  13. 9
    2
      src/terraingen.cpp
  14. 18
    0
      src/voxelinfo.cpp
  15. 24
    30
      src/world.cpp

+ 3
- 0
.gitmodules View File

@@ -1,3 +1,6 @@
[submodule "spdlog"]
path = spdlog
url = https://github.com/gabime/spdlog.git
[submodule "libcuckoo"]
path = libcuckoo
url = https://github.com/efficient/libcuckoo.git

+ 2
- 1
CMakeLists.txt View File

@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 3.6)
project ("voxeltronik")
file (GLOB_RECURSE SOURCES "src/*.cpp" "src/*.c")
include_directories("./include")
include_directories("./include" "libcuckoo/libcuckoo")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "-O2")
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
@@ -11,3 +11,4 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
target_link_libraries(vtk SDL2 GL GLEW GLU ${CMAKE_THREAD_LIBS_INIT})



+ 2
- 2
include/chunk.h View File

@@ -34,7 +34,7 @@ public:
bool isLoaded();

bool isVoxelSolid(const int& x, const int& y, const int& z); //Is the voxel not a transparent type?
void setVoxelType(const int& x, const int& y, const int& z, const unsigned& type);
void setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& update = false);
unsigned getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z);
glm::ivec3 getWorldCoords(const int& x, const int& y, const int& z);

@@ -48,7 +48,7 @@ protected:
std::array<unsigned, 4096> voxels;
World& mLinkedWorld;
glm::ivec3 mPos;
bool mLoaded;
std::atomic<bool> mLoaded;
};

}

+ 6
- 1
include/voxelinfo.h View File

@@ -52,6 +52,7 @@ enum class Orientation2D {
struct VoxelData{
std::map<Face3D, float> faceTextureIndices;
std::map<Face3D, Orientation2D> faceOrientation;
std::map<FaceDirection, unsigned> faceTextures;

bool transparent;
};
@@ -63,11 +64,15 @@ public:
void pushTexCoordFromWorldCoords(std::vector<float>& data, const glm::ivec3& pos, const Face3D& face, const Corner2D& corner);
void pushTexCoordFromVoxelID(std::vector<float>& data, const unsigned& id, const Face3D& face, const Corner2D& corner);
float getTexIndexFromID(const unsigned& id, const Face3D& face);
unsigned getTextureIndex(const unsigned& id, const FaceDirection& face);
void setTextureIndex(const unsigned& id, const FaceDirection& face, const unsigned& index);

void setAllTextureIndexes(const unsigned& id, const unsigned& index);
void setTextureData(const unsigned& id, const Face3D& face, const Orientation2D& orientation, const float& textureIndex);

void setTransparent(const unsigned& id, const bool& transparent);
bool isTransparent(const unsigned& id);
bool isTransparent(const unsigned& id);

std::pair<float, float> getTexCoordFromID(const unsigned& id, const Face3D& face, const Corner2D& corner);


+ 14
- 1
include/voxelutils.h View File

@@ -23,6 +23,15 @@

namespace vtk {

enum class FaceDirection {
TOP = 0,
BOTTOM = 1,
NORTH = 2,
SOUTH = 3,
EAST = 4,
WEST = 5
};

typedef std::tuple<unsigned, unsigned, unsigned> uPos; //used for voxel positions

struct uPosHash : public std::unary_function<uPos, std::size_t> {
@@ -58,7 +67,11 @@ struct iPosEqual : public std::binary_function<iPos, iPos, bool> {
// basic hash function for glm::ivec3
struct ivec3Hash : public std::unary_function<iPos, std::size_t> {
std::size_t operator()(const glm::ivec3& k) const {
return k.x ^ k.y ^ k.z;
std::size_t seed = 3;
for(int i = 0; i < 3; ++i) {
seed ^= k[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};


+ 3
- 1
include/world.h View File

@@ -23,6 +23,7 @@
#include "voxelmath.h"
#include "terraingen.h"
#include "graphics/chunkmesh.h"
#include "cuckoohash_map.hh"

#include <unordered_map>
#include <vector>
@@ -60,7 +61,8 @@ public:

void queueChunkLoadsAroundPoint(const glm::vec3& point, const int& chunkRadius);

std::unordered_map<glm::ivec3, Chunk*, ivec3Hash> mChunks;
//std::unordered_map<glm::ivec3, Chunk*, ivec3Hash> mChunks;
cuckoohash_map<glm::ivec3, Chunk*, ivec3Hash> mChunks;
std::unordered_map<glm::ivec3, ChunkMesh, ivec3Hash> mChunkMeshes;
std::vector<iPos> chunkUpdateQueue;
std::deque<glm::ivec3> mChunkUpdateQueue;

+ 1
- 0
libcuckoo

@@ -0,0 +1 @@
Subproject commit 6591795a944fa8c7268848d181ba2852f4a7897f

+ 19
- 17
res/shaders/voxelvert.vert.glsl View File

@@ -5,31 +5,33 @@ layout(location = 0) in uint position;
//layout(location = 1) in vec3 texCoord;
layout(location = 1) in uint face_attrib;

uniform mat4 proj, view, model; //transform matrix
uniform mat4 proj, view, model; //transform matrix

out vec3 texCoordInterp;
out vec3 lightDataInterp;
out vec4 eyeSpacePos;
out vec3 texCoordInterp;
out vec3 lightDataInterp;
out vec4 eyeSpacePos;

void main() {
vec3 pos_unpacked;
pos_unpacked.x = float((position >> 8u) & 15u) / 15.0f;
pos_unpacked.y = float((position >> 4u) & 15u) / 15.0f;
pos_unpacked.z = float((position) & 15u) / 15.0f;
void main() {
vec3 pos_unpacked;
pos_unpacked.x = float((position >> 8u) & 15u) / 15.0f;
pos_unpacked.y = float((position >> 4u) & 15u) / 15.0f;
pos_unpacked.z = float((position) & 15u) / 15.0f;

vec2 uv_unpacked;
uv_unpacked.x = float((position >> 16u) & 15u) / 15.0f;
uv_unpacked.y = float((position >> 12u) & 15u) / 15.0f;
vec2 uv_unpacked;
uv_unpacked.x = float((position >> 16u) & 15u) / 15.0f;
uv_unpacked.y = float((position >> 12u) & 15u) / 15.0f;

vec3 offset_unpacked;
offset_unpacked.x = float((face_attrib >> 10u) & 31u);
offset_unpacked.y = float((face_attrib >> 5u) & 31u);
offset_unpacked.z = float((face_attrib) & 31u);
vec3 offset_unpacked;
offset_unpacked.x = float((face_attrib >> 10u) & 31u);
offset_unpacked.y = float((face_attrib >> 5u) & 31u);
offset_unpacked.z = float((face_attrib) & 31u);

float tex_index = float(face_attrib >> 15u);

vec3 final_position = pos_unpacked + offset_unpacked;
vec4 eyeSpacePosVert = view * model * vec4(final_position, 1.0);
gl_Position = proj * eyeSpacePosVert;
texCoordInterp = vec3(uv_unpacked, 2.0f);//texCoord;
texCoordInterp = vec3(uv_unpacked, tex_index);//texCoord;
lightDataInterp = vec3(1.0f, 1.0f, 1.0f);
eyeSpacePos = eyeSpacePosVert;
}

+ 218
- 0
src/2 View File

@@ -0,0 +1,218 @@
#include "world.h"
#include "chunk.h"
#include "threadpool.h"

#include <cmath>
#include <iostream>
#include <thread>

#include <GL/glew.h>
#include <GL/gl.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

namespace vtk {

World::World() {
chunkSize = 16;
voxelSize = 1.0f;
voxelInfo.linkedWorld = this;
voxelMath.linkedWorld = this;
rebuildThreadActive = false;
mLoadThreadActive = false;
}

bool World::isVoxelSolid(const int& x, const int& y, const int& z) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize),
floor((float)y / (float)chunkSize),
floor((float)z / (float)chunkSize));
auto chunk = getChunk(chunkPos);
if (chunk) //block is in nonexistant chunk
return true;

int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;

if (!chunk->isLoaded()) return true;
return chunk->isVoxelSolid(relPosX, relPosY, relPosZ);
}

bool World::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& updateChunk) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize), floor((float)y / (float)chunkSize), floor((float)z / (float)chunkSize));
auto chunk = getChunk(chunkPos);
if (!chunk) return false;

int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;

chunk->setVoxelType(relPosX, relPosY, relPosZ, type, updateChunk);
return true;
}

unsigned World::getVoxelType(const glm::ivec3& pos) {
auto chunkPos = glm::ivec3(floor((float)pos.x / (float)chunkSize),
floor((float)pos.y / (float)chunkSize),
floor((float)pos.z / (float)chunkSize));
Chunk* chunk;
if (!mChunks.find(chunkPos, chunk)) {
return 0;
}

int relPosX = pos.x - chunkPos.x * chunkSize;
int relPosY = pos.y - chunkPos.y * chunkSize;
int relPosZ = pos.z - chunkPos.z * chunkSize;

return chunk->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
}


Chunk* World::makeChunk(const int& x, const int& y, const int& z, bool insertAfter) {
auto pos = glm::ivec3(x, y, z);

Chunk* chunk;
if (mChunks.find(pos, chunk)) { //chunk already exists
return chunk;
}

chunk = new Chunk(*this);
chunk->setPos(pos);

if (insertAfter) insertChunk(chunk);
return chunk;
}

bool World::generateChunk(const int& x, const int& y, const int& z) {
auto chunkMade = makeChunk(x,y,z, false);
if (chunkMade != nullptr) {
terrain.generateChunk(chunkMade);
//queue this chunk for geometry update
queueChunkUpdate(x,y,z);

//queue the neighboring 6 chunks. the queue functions throws them out
// if they don't exist
queueChunkUpdate(x+1,y,z);
queueChunkUpdate(x-1,y,z);
queueChunkUpdate(x,y+1,z);
queueChunkUpdate(x,y-1,z);
queueChunkUpdate(x,y,z+1);
queueChunkUpdate(x,y,z-1);
}
insertChunk(chunkMade);
return chunkMade;
}

bool World::insertChunk(Chunk* chunk) {
mChunks.insert(chunk->getPos(), chunk);
mChunkMeshes.emplace(chunk->getPos(), ChunkMesh(*this, chunk->getPos()));
return true;
}


Chunk* World::getChunk(const glm::ivec3& pos) {
Chunk* chunk;
if (mChunks.find(pos, chunk)) return chunk;
else return nullptr;
}

void World::queueChunkUpdate(const int& x, const int& y, const int& z, const bool& back) {
queueChunkUpdate(glm::ivec3(x,y,z));
}

void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
if (!getChunk(pos)) return; //chunk doesn't exist
for (auto& i : mChunkUpdateQueue) {
if (i == pos) return; //chunk is already in queue, we don't need to update multiple times
}

if (back) {
mChunkUpdateQueue.push_back(pos);
} else {
mChunkUpdateQueue.push_front(pos);
}
}

void World::queueChunkLoad(const glm::ivec3 &pos) {
if (getChunk(pos)) return; //chunk already exists
for (auto& i : mChunkLoadQueue) {
if (i == pos) return;
}

makeChunk(pos.x, pos.y, pos.z);
mChunkLoadQueue.push_back(pos);
}

void World::draw() {
for (auto& i : mChunkMeshes) {
glm::mat4 modelMat = glm::translate(glm::mat4(), glm::vec3((float)i.first.x * 16,
(float)i.first.y * 16,
(float)i.first.z * 16
));

glUniformMatrix4fv(modelMatUni, 1, GL_FALSE, glm::value_ptr(modelMat));
i.second.draw();
}
}

void World::update() {
if (!rebuildThreadActive && !mChunkUpdateQueue.empty( )) {
auto updatefunc = [&]() {
while (!mChunkUpdateQueue.empty()) {
auto& pos = mChunkUpdateQueue.back();
auto& mesh = mChunkMeshes.find(pos)->second;
mChunkUpdateQueue.pop_back();
if (!mesh.rebuildChunkGeometry())
queueChunkUpdate(pos);
}
rebuildThreadActive = false;
};

rebuildThreadActive = true;
ThreadPool::getInstance().addJob(updatefunc);
}

if (!mLoadThreadActive && !mChunkLoadQueue.empty()) {
auto loadFunc = [&]() {
while (!mChunkLoadQueue.empty()) {
auto& pos = mChunkLoadQueue.back();
generateChunk(pos.x, pos.y, pos.z);
mChunkLoadQueue.pop_back();
}
mLoadThreadActive = false;
};

mLoadThreadActive = true;
ThreadPool::getInstance().addJob(loadFunc);
}
}

void World::forceGlobalGeometryUpdate() {
int chunkCount = 1;
chunkCount = 1;
for (auto& i : mChunkMeshes) {
std::cout << "\rUpdating chunk geometry, but better (" << chunkCount << "/" << mChunkMeshes.size() << ")" << std::flush;
i.second.rebuildChunkGeometry();
i.second.updateGeometry();
++chunkCount;
}
}

void World::queueChunkLoadsAroundPoint(const glm::vec3 &point, const int &chunkRadius) {
glm::ivec3 chunkPoint = point / 16.0f;
for (int z = -chunkRadius; z <= chunkRadius; ++z) {
for (int x = -chunkRadius; x <= chunkRadius; ++x) {
if (z*z + x*x <= chunkRadius * chunkRadius) {
for (int y = 0; y < 8; ++y) {
queueChunkLoad(glm::ivec3(x + chunkPoint.x, y, z + chunkPoint.z));
}
}
}
}
}

}


+ 5
- 3
src/chunk.cpp View File

@@ -37,7 +37,7 @@ Chunk::Chunk(World& world) :
}

bool Chunk::isLoaded() {
return mLoaded;
return mLoaded.load();
}

bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
@@ -45,7 +45,7 @@ bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
y < 0 || y > 15 ||
z < 0 || z > 15 )
{ //position is outside of the chunk
return mLinkedWorld.isVoxelSolid(mPos.x * 16 + x,
return mLinkedWorld.isVoxelSolid(mPos.x * 16 + x,
mPos.y * 16 + y,
mPos.z * 16 + z);
}
@@ -53,7 +53,7 @@ bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
return (getVoxelType((unsigned)x,(unsigned)y,(unsigned)z) != 0);
}

void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type) {
void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& update) {
auto index = x + 16 * (y + 16 * z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (set voxel): Out of range, doing nothing\n";
@@ -61,6 +61,8 @@ void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigne
}
voxels[index] = type;

if (!update) return;
mLinkedWorld.queueChunkUpdate(mPos);
}

unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {

+ 6
- 2
src/graphics/chunkmesh.cpp View File

@@ -65,17 +65,21 @@ bool ChunkMesh::rebuildChunkGeometry() {
//build face attrib
// 0b00000000000000000xxxxxyyyyyzzzzz
unsigned faceAttrib = 0;
faceAttrib = faceAttrib | i;
faceAttrib = (faceAttrib << 5) | i;
faceAttrib = (faceAttrib << 5) | j;
faceAttrib = (faceAttrib << 5) | k;

//lambda expression for adding vertices
auto addFaceModel = [&](int faceIndex) {
auto mesh = mVoxelModel.getFaceMesh(faceIndex);
unsigned texIndex = mLinkedWorld.voxelInfo.getTextureIndex(chunk->getVoxelType(i,j,k),
static_cast<FaceDirection>(faceIndex));
unsigned faceAttribT = faceAttrib | (texIndex << 15); // pack texture index into faceAttrib

++mFaceCount;
for (int l = 0; l < 6; ++l) {
mGeometry.push_back(mesh[l]);
mFaceAttribs.push_back(faceAttrib);
mFaceAttribs.push_back(faceAttribT);
}
};


+ 6
- 30
src/scenes/testscene.cpp View File

@@ -44,7 +44,7 @@ void TestScene::init() {
tiles.buildTexture();
tiles.updateTextureAt(0, "res/stone.png");
tiles.updateTextureAt(1, "res/dirt.png");
tiles.updateTextureAt(2, "res/test.png");
tiles.updateTextureAt(2, "res/grass.png");

//shaders
shaders = LoadShaders("res/shaders/voxelvert.vert.glsl", "res/shaders/voxelfrag.frag.glsl");
@@ -105,23 +105,16 @@ void TestScene::init() {
world.voxelInfo.setTextureData(2, Face3D::FRONT, Orientation2D::UP, 1.0f);
world.voxelInfo.setTextureData(2, Face3D::BACK, Orientation2D::UP, 1.0f);


world.voxelInfo.setAllTextureIndexes(1, 0);
world.voxelInfo.setAllTextureIndexes(2, 1);
world.voxelInfo.setTextureIndex(2, FaceDirection::TOP, 2);

//world.voxelInfo.setTransparent(1, false);
//world.voxelInfo.setTransparent(2, false);

std::cout << std::endl;

/*
int chunkCount = 1;
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 32; k++) {
std::cout << "\rGenerating chunks (" << chunkCount << "/" << 8*8*8 << ")" << std::flush;
world.queueChunkLoad(glm::ivec3(i,j,k));
chunkCount++;
}
}
}
*/
world.queueChunkLoadsAroundPoint(glm::vec3(0.0,0.0,0.0), 16);

//world.forceGlobalGeometryUpdate();
@@ -171,28 +164,11 @@ void TestScene::update(const float& dTime) {
placeVoxel = false;
}

//camera.moveRelative(camMovement * dTime);


float distance = glm::distance(camera.getPosition(), mCamLastLoadPosition);
if (distance >= 16.0f) {
mCamLastLoadPosition = camera.getPosition();
world.queueChunkLoadsAroundPoint(camera.getPosition(), 16);
}
//generate chunks with camera (doesn't work very well :|)
/*
int radius = 2;
auto cPos = camera.getPosition();
glm::ivec3 cPosI = (cPos / 16.0f);
for (int y = -radius; y <= radius; ++y) {
for (int x = -radius; x <= radius; ++x) {
if(x*x + y*y <= radius*radius) {
for (int i = 0; i < 8; ++i)
world.queueChunkLoad((glm::ivec3)cPos + glm::ivec3(x, i, y));
}
}
}
*/
}


+ 9
- 2
src/terraingen.cpp View File

@@ -32,7 +32,7 @@ namespace vtk {
TerrainGen::TerrainGen() {
std::shared_ptr<noise::NoiseModule> noise = std::make_shared<noise::Noise>(6969696);
std::shared_ptr<noise::NoiseModule> yGrad = std::make_shared<noise::YGradient>(0.0, 128.0);
mNoise = std::make_shared<noise::YTurbulence>(yGrad, noise, 60.0);
mNoise = std::make_shared<noise::YTurbulence>(yGrad, noise, 15.0);

mTerrainScale = 32.0;
}
@@ -48,7 +48,14 @@ void TerrainGen::generateChunk(Chunk* chunk) {
(double)(chunkPos.y * 16 + j),
(double)(chunkPos.z * 16 + k));
if (nVal <= 0.0) {
chunk->setVoxelType(i,j,k,1);
if (mNoise->get3D((double)(chunkPos.x * 16 + i),
(double)(chunkPos.y * 16 + j + 1),
(double)(chunkPos.z * 16 + k)) >= 0.0)
{
chunk->setVoxelType(i, j, k, 2);
} else {// block above is air
chunk->setVoxelType(i,j,k,1);
}
} else {
chunk->setVoxelType(i,j,k,0);
}

+ 18
- 0
src/voxelinfo.cpp View File

@@ -110,6 +110,24 @@ std::pair<float, float> VoxelInfo::getTexCoordFromID(const unsigned& id, const F
return std::make_pair(0.0f, 0.0f);
}

unsigned VoxelInfo::getTextureIndex(const unsigned int &id, const FaceDirection &face) {
return voxelDataMap[id].faceTextures[face];
}

void VoxelInfo::setTextureIndex(const unsigned int &id, const FaceDirection &face, const unsigned int &index) {
voxelDataMap[id].faceTextures[face] = index;
}

void VoxelInfo::setAllTextureIndexes(const unsigned int &id, const unsigned int &index) {
auto& textures = voxelDataMap[id].faceTextures;
textures[FaceDirection::TOP] = index;
textures[FaceDirection::BOTTOM] = index;
textures[FaceDirection::NORTH] = index;
textures[FaceDirection::SOUTH] = index;
textures[FaceDirection::EAST] = index;
textures[FaceDirection::WEST] = index;
}

void VoxelInfo::setTextureData(const unsigned& id, const Face3D& face, const Orientation2D& orientation, const float& textureIndex) {
voxelDataMap[id].faceOrientation[face] = orientation;
voxelDataMap[id].faceTextureIndices[face] = textureIndex;

+ 24
- 30
src/world.cpp View File

@@ -29,30 +29,28 @@ bool World::isVoxelSolid(const int& x, const int& y, const int& z) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize),
floor((float)y / (float)chunkSize),
floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
auto chunk = getChunk(chunkPos);
if (!chunk) //block is in nonexistant chunk
return true;
}

int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;

if (!mChunks[chunkPos]->isLoaded()) return true;
return mChunks[chunkPos]->isVoxelSolid(relPosX, relPosY, relPosZ);
if (!chunk->isLoaded()) return true;
return chunk->isVoxelSolid(relPosX, relPosY, relPosZ);
}

bool World::setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& updateChunk) {
auto chunkPos = glm::ivec3(floor((float)x / (float)chunkSize), floor((float)y / (float)chunkSize), floor((float)z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) { //block is in nonexistant chunk
return false;
}
auto chunk = getChunk(chunkPos);
if (!chunk) return false;

int relPosX = x - chunkPos.x * chunkSize;
int relPosY = y - chunkPos.y * chunkSize;
int relPosZ = z - chunkPos.z * chunkSize;

mChunks[chunkPos]->setVoxelType(relPosX, relPosY, relPosZ, type);
if (updateChunk) queueChunkUpdate(chunkPos, true);
chunk->setVoxelType(relPosX, relPosY, relPosZ, type, updateChunk);
return true;
}

@@ -60,34 +58,30 @@ unsigned World::getVoxelType(const glm::ivec3& pos) {
auto chunkPos = glm::ivec3(floor((float)pos.x / (float)chunkSize),
floor((float)pos.y / (float)chunkSize),
floor((float)pos.z / (float)chunkSize));
if (mChunks.find(chunkPos) == mChunks.end()) {
return 0;
}

Chunk* chunk = getChunk(chunkPos);
if (!chunk) return 0;
int relPosX = pos.x - chunkPos.x * chunkSize;
int relPosY = pos.y - chunkPos.y * chunkSize;
int relPosZ = pos.z - chunkPos.z * chunkSize;

return mChunks[chunkPos]->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
return chunk->getVoxelType((unsigned)relPosX, (unsigned)relPosY, (unsigned)relPosZ);
}


Chunk* World::makeChunk(const int& x, const int& y, const int& z, bool insertAfter) {
auto pos = glm::ivec3(x, y, z);

if (mChunks.find(pos) != mChunks.end()) { //chunk already exists
return mChunks[pos];
Chunk* chunk;
if (mChunks.find(pos, chunk)) { //chunk already exists
return chunk;
}

auto newChunk = new Chunk(*this);
newChunk->setPos(pos);

if (insertAfter) {
mChunks[pos] = newChunk;
mChunkMeshes.emplace(pos, ChunkMesh(*this, pos));
}
chunk = new Chunk(*this);
chunk->setPos(pos);

return newChunk;
if (insertAfter) insertChunk(chunk);
return chunk;
}

bool World::generateChunk(const int& x, const int& y, const int& z) {
@@ -111,15 +105,15 @@ bool World::generateChunk(const int& x, const int& y, const int& z) {
}

bool World::insertChunk(Chunk* chunk) {
mChunks[chunk->getPos()] = chunk;
mChunks.insert(chunk->getPos(), chunk);
mChunkMeshes.emplace(chunk->getPos(), ChunkMesh(*this, chunk->getPos()));
return true;
}


Chunk* World::getChunk(const glm::ivec3& pos) {
auto chunk = mChunks.find(pos)->second;
if (chunk) return chunk;
Chunk* chunk;
if (mChunks.find(pos, chunk) && chunk->isLoaded()) return chunk;
else return nullptr;
}

@@ -128,7 +122,7 @@ void World::queueChunkUpdate(const int& x, const int& y, const int& z, const boo
}

void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
if (mChunks.find(pos) == mChunks.end()) return; //chunk doesn't exist
if (!getChunk(pos)) return; //chunk doesn't exist
for (auto& i : mChunkUpdateQueue) {
if (i == pos) return; //chunk is already in queue, we don't need to update multiple times
}
@@ -141,7 +135,7 @@ void World::queueChunkUpdate(const glm::ivec3& pos, const bool& back) {
}

void World::queueChunkLoad(const glm::ivec3 &pos) {
if (mChunks.find(pos) != mChunks.end()) return; //chunk already exists
if (getChunk(pos)) return; //chunk already exists
for (auto& i : mChunkLoadQueue) {
if (i == pos) return;
}
@@ -170,7 +164,7 @@ void World::update() {
auto& mesh = mChunkMeshes.find(pos)->second;
mChunkUpdateQueue.pop_back();
if (!mesh.rebuildChunkGeometry())
queueChunkUpdate(pos, false);
queueChunkUpdate(pos);
}
rebuildThreadActive = false;
};

Loading…
Cancel
Save