Browse Source

C++17 and broken sunlight propogation

testing
totallyfake 1 year ago
parent
commit
3895b3705e
8 changed files with 133 additions and 51 deletions
  1. 1
    1
      CMakeLists.txt
  2. 6
    0
      include/chunk.h
  3. 4
    18
      include/voxelinfo.h
  4. 4
    0
      include/voxelutils.h
  5. 96
    10
      src/chunk.cpp
  6. 8
    18
      src/voxelinfo.cpp
  7. 12
    0
      src/voxelutils.cpp
  8. 2
    4
      src/world.cpp

+ 1
- 1
CMakeLists.txt View File

@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.6)
project ("voxeltronik")
file (GLOB_RECURSE SOURCES "src/*.cpp" "src/*.c")
include_directories("./include" "libcuckoo/libcuckoo")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-O2")
set(CMAKE_C_FLAGS "-fPIC")
set(CMAKE_EXPORT_COMPILE_COMMANDS on)

+ 6
- 0
include/chunk.h View File

@@ -10,6 +10,8 @@ namespace vtk {
class World;
class HeightMap;

typedef std::pair<short, unsigned short> LightIndexPair;

class Chunk {
friend class World;
public:
@@ -26,6 +28,7 @@ public:
bool placeVoxel(const glm::ivec3& pos, const unsigned& type);
bool isVoxelSolid(const int& x, const int& y, const int& z); //Is the voxel not a transparent type?
bool isVoxelSolid(const glm::ivec3& pos);

void setVoxelType(const glm::ivec3& pos, const unsigned& type);
void setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& update = false);
@@ -33,9 +36,11 @@ public:
unsigned getVoxelType(const glm::ivec3& pos);
unsigned getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z);

void rebuildLighting();
glm::ivec3 getWorldCoords(const int& x, const int& y, const int& z);
unsigned getLightLevel(const glm::ivec3& pos);
unsigned short getLightPacked(const glm::ivec3& pos);
void setLightPacked(const glm::ivec3& pos, const unsigned short& light);
HeightMap* getHeightMap();

void setPos(const glm::ivec3& pos);
@@ -44,6 +49,7 @@ public:


protected:
typedef std::tuple<short, Chunk*> LightIndexTup;
void setQueuedForMeshRebuild(const bool& rebuild = true);
bool isQueuedForMeshRebuild();


+ 4
- 18
include/voxelinfo.h View File

@@ -1,21 +1,3 @@
/*
* =====================================================================================
*
* Filename: voxelinfo.h
*
* Description: Stores information about voxel types, like texture coordinates.
*
* Version: 1.0
* Created: 04/06/2014 01:07:52 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/

#pragma once

#include "voxelutils.h"
@@ -55,6 +37,7 @@ struct VoxelData{
std::map<FaceDirection, unsigned> faceTextures;

bool transparent;
unsigned short emission;
};

class World;
@@ -76,6 +59,9 @@ public:

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

void setEmission(const unsigned& id, const unsigned short& emission);
unsigned short getEmission(const unsigned& id);

World* linkedWorld;

protected:

+ 4
- 0
include/voxelutils.h View File

@@ -23,6 +23,10 @@ glm::ivec2 worldPosToChunkPos(const glm::ivec2& pos);
//takes chunk and local positions, returns a world position
glm::ivec3 chunkPosToWorldPos(const glm::ivec3& cPos, const glm::ivec3& lPos);

//takes a chunk/local pos and returns a chunk,local pos pair (works for out of bounds coords)
std::pair<glm::ivec3, glm::ivec3> worldPosToLocalPos(const glm::ivec3& pos);
std::pair<glm::ivec3, glm::ivec3> localPosToLocalPos(const glm::ivec3& cPos, const glm::ivec3& lPos);

/*
//TODO: move this to cpp file
constexpr glm::ivec3 FaceDirectionToVec(const FaceDirection& direction) {

+ 96
- 10
src/chunk.cpp View File

@@ -2,6 +2,7 @@
#include "world.h"

#include <iostream>
#include <queue>

namespace vtk {

@@ -17,7 +18,7 @@ Chunk::Chunk(World& world) :
mData[i].store(0);
}
for (unsigned i = 0; i < mLighting.size(); ++i) {
mLighting[i].store(0);
mLighting[i].store(0xFFFF);
}

mLoaded.store(true);
@@ -76,10 +77,12 @@ bool Chunk::placeVoxel(const glm::ivec3& pos, const unsigned& type) {
mLinkedWorld.getHeightMap(glm::ivec2(mPos.x, mPos.z))
->blockHeight(glm::ivec3(pos.x, pos.y + mPos.y * 16, pos.z));

mLinkedWorld.queueChunkUpdate(mPos);
mLinkedWorld.queueChunkUpdate(mPos, true);


//update the neightboring chunks if voxel lies along border

// TODO: make this a function in voxelutils(voxelmath?)
glm::ivec3 neighborPos(0,0,0);

if (pos.x == 0) neighborPos.x--;
@@ -120,6 +123,10 @@ bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
return !mLinkedWorld.voxelInfo.isTransparent(getVoxelType((unsigned)x, (unsigned)y, (unsigned)z));
}

bool Chunk::isVoxelSolid(const glm::ivec3& pos) {
return isVoxelSolid(pos.x, pos.y, pos.z);
}

void Chunk::setVoxelType(const glm::ivec3 &pos, const unsigned& type) {
setVoxelType(pos.x, pos.y, pos.z, type);
}
@@ -148,6 +155,75 @@ unsigned Chunk::getVoxelType(const glm::ivec3& pos) {
unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {
return getVoxelType(glm::ivec3(x,y,z));
}

void Chunk::rebuildLighting() {
std::queue<LightIndexTup> sunBFSQueue;
//FIRST PASS, block out all solid blocks
for (short i = 0; i < 4096; ++i) {
glm::ivec3 pos(i % 16, (i / 16) % 16,(i / 256)); // get current coord
mLighting[i].store(0);
auto lightVal = mLinkedWorld.voxelInfo.getEmission(getVoxelType(pos));

//set sunlighting if at the top of chunk and above the ground
if(pos.y == 15 &&
mLinkedWorld.getHeightMap(glm::ivec2(mPos.x, mPos.z))
->getHeight(glm::ivec2(pos.x, pos.z)) <=
pos.y + mPos.y * 16)
{
lightVal = lightVal | 0xF; //max out the sun lighting
}
mLighting[i].store(lightVal);
if ((lightVal & 0xF) != 0) {
sunBFSQueue.push(std::make_tuple(i,this));
}

}
//iterate through sunlight
while (!sunBFSQueue.empty()) {
short index;
Chunk* chunk;
unsigned short light;
std::tie(index, chunk) = sunBFSQueue.front();
light = light & 0xF; // so I don't have to remask every time
glm::ivec3 pos( index % 16,
(index / 16) % 16,
index / 256);
light = chunk->getLightPacked(pos) & 0xF;

auto propogateSun =
[&](glm::ivec3 nPos, Chunk* nChunk)
{
bool straightDown = (pos.y > nPos.y && light == 0xF);
auto checkPos = localPosToLocalPos(nChunk->getPos(), nPos);
nChunk = mLinkedWorld.getChunk(checkPos.first);
nPos = checkPos.second;
auto newLight = chunk->getLightPacked(nPos) & 0xF;
if (!chunk->isVoxelSolid(nPos)) {
if (light >= newLight + 2) {
if (straightDown) {
chunk->setLightPacked(nPos, (newLight & 0xFFF0) | 0xF);
}
chunk->setLightPacked(nPos, (newLight & 0xFFF0) | light - 1);
if (light - 1 > 1) {
sunBFSQueue.push(std::make_tuple((short)(nPos.x + 16 * (nPos.y + 16 * nPos.z)), chunk));
}
}
}
};
//visit neighbors
propogateSun(glm::ivec3(pos.x-1, pos.y, pos.z), this);
propogateSun(glm::ivec3(pos.x+1, pos.y, pos.z), this);
propogateSun(glm::ivec3(pos.x, pos.y-1, pos.z), this);
propogateSun(glm::ivec3(pos.x, pos.y+1, pos.z), this);
propogateSun(glm::ivec3(pos.x, pos.y, pos.z-1), this);
propogateSun(glm::ivec3(pos.x, pos.y, pos.z+1), this);

sunBFSQueue.pop();
}
}

glm::ivec3 Chunk::getWorldCoords(const int& x, const int& y, const int& z) {
return glm::ivec3(mPos.x * 16 + x,
mPos.y * 16 + y,
@@ -162,15 +238,25 @@ unsigned Chunk::getLightLevel(const glm::ivec3 &pos) {
}

unsigned short Chunk::getLightPacked(const glm::ivec3 &pos) {
if (isVoxelSolid(pos.x, pos.y, pos.z)) {
return 0x0000;
}
auto wPos = chunkPosToWorldPos(mPos, pos);
if (mLinkedWorld.getHeight(glm::ivec2(wPos.x, wPos.z)) > wPos.y) { //voxel is below ground
//std::cout << mLinkedWorld.getHeight(glm::ivec2(pos.x, pos.z)) << ", ";
return 0x000A;
//checking if pos is inside current chunk
auto lPos = localPosToLocalPos(mPos, pos); //returns a chunk/local pos pair

if (lPos.first != mPos) { //if it's not THIS chunk
auto chunk = mLinkedWorld.getChunk(lPos.first);
if (chunk)
return chunk->getLightPacked(lPos.second);
else
return 0xFFFF;
}
return 0x000F;
int index = pos.x + 16 * (pos.y + 16 * pos.z);

return mLighting[index].load();
}

void Chunk::setLightPacked(const glm::ivec3& pos, const unsigned short& light) {
int index = pos.x + 16 * (pos.y + 16 * pos.z);
mLighting[index].store(light);
}

HeightMap* Chunk::getHeightMap() {

+ 8
- 18
src/voxelinfo.cpp View File

@@ -1,21 +1,3 @@

/*
* =====================================================================================
*
* Filename: voxelinfo.cpp
*
* Description: Voxelinfo source file
*
* Version: 1.0
* Created: 04/06/2014 01:30:10 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
#include "voxelinfo.h"
#include "world.h"

@@ -141,5 +123,13 @@ bool VoxelInfo::isTransparent(const unsigned& id) {
return voxelDataMap[id].transparent;
}

void VoxelInfo::setEmission(const unsigned int &id, const unsigned short &emission) {
voxelDataMap[id].emission = emission;
}

unsigned short VoxelInfo::getEmission(const unsigned int &id) {
return voxelDataMap[id].emission;
}

}


+ 12
- 0
src/voxelutils.cpp View File

@@ -18,4 +18,16 @@ glm::ivec2 worldPosToChunkPos(const glm::ivec2& pos) {
glm::ivec3 chunkPosToWorldPos(const glm::ivec3& cPos, const glm::ivec3& lPos) {
return glm::ivec3((cPos * 16) + lPos);
}

std::pair<glm::ivec3, glm::ivec3> worldPosToLocalPos(const glm::ivec3& pos) {
auto cPos = worldPosToChunkPos(pos);
auto lPos = pos - (16 * cPos);
return std::make_pair(cPos, lPos);
}

std::pair<glm::ivec3, glm::ivec3> localPosToLocalPos(const glm::ivec3& cPos, const glm::ivec3& lPos) {
glm::ivec3 wPos = chunkPosToWorldPos(cPos, lPos); // get world coords
return worldPosToLocalPos(wPos);
}
}

+ 2
- 4
src/world.cpp View File

@@ -214,12 +214,9 @@ void World::update() {
auto updatefunc = [&]() {
glm::ivec3 pos;
glm::ivec2 hm_pos;
while (mHeightMapUpdateQueue.try_dequeue(hm_pos)) {
auto heightMap = getHeightMap(hm_pos);
heightMap->flushUpdates();
}
while (mMeshUpdateQueueSoon.try_dequeue(pos)) {
getChunk(pos)->rebuildLighting();
ChunkMesh* mesh;
mChunkMeshes.find(pos, mesh);
if (mesh) {
@@ -229,6 +226,7 @@ void World::update() {
}
while (mMeshUpdateQueue.try_dequeue(pos)) {
getChunk(pos)->rebuildLighting();
ChunkMesh* mesh;
mChunkMeshes.find(pos, mesh);
if (mesh) {

Loading…
Cancel
Save