Browse Source

break/place funcs

testing
totallyfake 1 year ago
parent
commit
7fefaa89d9
5 changed files with 115 additions and 9 deletions
  1. 14
    4
      include/chunk.h
  2. 4
    0
      include/world.h
  3. 71
    3
      src/chunk.cpp
  4. 4
    2
      src/scenes/testscene.cpp
  5. 22
    0
      src/world.cpp

+ 14
- 4
include/chunk.h View File

@@ -1,8 +1,6 @@
#pragma once

#include "voxelutils.h"
#include "chunkrenderer.h"
#include "graphics/chunkmesh.h"
#include "util/mobileatomic.h"

#include <glm/glm.hpp>
@@ -18,9 +16,23 @@ public:
Chunk(World& world);
bool isLoaded();

// BREAK AND PLACE FUNCS
// These handle all the mesh rebuilds and heightmap updates for you
// Positions are chunk relative (0-15 on all axes)
//break a voxel, returns the type of the voxel that was just broken
unsigned breakVoxel(const glm::ivec3& pos);
//place voxel, will not override previous voxels, returns true if successful
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?

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);

unsigned getVoxelType(const glm::ivec3& pos);
unsigned getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z);

glm::ivec3 getWorldCoords(const int& x, const int& y, const int& z);
unsigned getLightLevel(const glm::ivec3& pos);
unsigned getLightPacked(const glm::ivec3& pos);
@@ -31,13 +43,11 @@ public:
World& getWorld();


ChunkRenderer renderer;
protected:
void setQueuedForMeshRebuild(const bool& rebuild = true);
bool isQueuedForMeshRebuild();

std::array<util::MobileAtomic<unsigned>, 4096> mData;
//std::array<unsigned, 4096> voxels;
World& mLinkedWorld;
glm::ivec3 mPos;
std::atomic<bool> mLoaded;

+ 4
- 0
include/world.h View File

@@ -23,6 +23,10 @@ class World {
friend class Chunk;
public:
World();

unsigned breakVoxel(const glm::ivec3& pos);
bool placeVoxel(const glm::ivec3& pos, const unsigned& id);
bool isVoxelSolid(const int& x, const int& y, const int& z);

bool setVoxelType(const int& x, const int& y, const int& z, const unsigned& type, const bool& updateChunk = false);

+ 71
- 3
src/chunk.cpp View File

@@ -28,7 +28,6 @@ Chunk::Chunk(World& world) :
mQueuedForMeshRebuild(false)
{
mPos = glm::ivec3(0,0,0);
renderer.linkedChunk = this;

//fill voxels with 0
for (unsigned i = 0; i < mData.size(); i++) {
@@ -41,6 +40,68 @@ bool Chunk::isLoaded() {
return mLoaded.load();
}

unsigned Chunk::breakVoxel(const glm::ivec3& pos) {
unsigned voxelType = getVoxelType(pos);
if (voxelType == 0) return voxelType; //return early if nothing broken

setVoxelType(pos, 0);

//update heightmap
mLinkedWorld.getHeightMap(glm::ivec2(mPos.x, mPos.z))
->unblockHeight(glm::ivec3(pos.x, pos.y + mPos.y * 16, pos.z));
mLinkedWorld.queueChunkUpdate(mPos);

//update the neightboring chunk if voxel lies along border
glm::ivec3 neighborPos(0,0,0);

if (pos.x == 0) neighborPos.x--;
else if (pos.x == 15) neighborPos.x++;

if (pos.y == 0) neighborPos.y--;
else if (pos.y == 15) neighborPos.y++;

if (pos.z == 0) neighborPos.z--;
else if (pos.z == 15) neighborPos.z++;
if (neighborPos != glm::ivec3(0,0,0)) {
mLinkedWorld.queueChunkUpdate(mPos + neighborPos);
}

return voxelType;
}

bool Chunk::placeVoxel(const glm::ivec3& pos, const unsigned& type) {
unsigned curType = getVoxelType(pos);
if (curType != 0) // return false if the voxel is NOT air
return false;
setVoxelType(pos, type);

//update heightmap
mLinkedWorld.getHeightMap(glm::ivec2(mPos.x, mPos.z))
->blockHeight(glm::ivec3(pos.x, pos.y + mPos.y * 16, pos.z));

mLinkedWorld.queueChunkUpdate(mPos);


//update the neightboring chunk if voxel lies along border
glm::ivec3 neighborPos(0,0,0);

if (pos.x == 0) neighborPos.x--;
else if (pos.x == 15) neighborPos.x++;

if (pos.y == 0) neighborPos.y--;
else if (pos.y == 15) neighborPos.y++;

if (pos.z == 0) neighborPos.z--;
else if (pos.z == 15) neighborPos.z++;
if (neighborPos != glm::ivec3(0,0,0)) {
mLinkedWorld.queueChunkUpdate(mPos + neighborPos);
}

return true;
}

bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
if (x < 0 || x > 15 ||
y < 0 || y > 15 ||
@@ -54,6 +115,10 @@ bool Chunk::isVoxelSolid(const int& x, const int& y, const int& z) {
return !mLinkedWorld.voxelInfo.isTransparent(getVoxelType((unsigned)x, (unsigned)y, (unsigned)z));
}

void Chunk::setVoxelType(const glm::ivec3 &pos, const unsigned& type) {
setVoxelType(pos.x, pos.y, pos.z, 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) {
@@ -66,8 +131,8 @@ void Chunk::setVoxelType(const int& x, const int& y, const int& z, const unsigne
mLinkedWorld.queueChunkUpdate(mPos);
}

unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {
auto index = x + 16 * (y + 16 * z);
unsigned Chunk::getVoxelType(const glm::ivec3& pos) {
auto index = pos.x + 16 * (pos.y + 16 * pos.z);
if (index > 4095) {
std::cout << "CHUNK ACCESS ERROR (get voxel): Out of range, returning type 0\n";
return 0;
@@ -75,6 +140,9 @@ unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigne
return mData[index].load(std::memory_order_consume);
}

unsigned Chunk::getVoxelType(const unsigned& x, const unsigned& y, const unsigned& z) {
return getVoxelType(glm::ivec3(x,y,z));
}
glm::ivec3 Chunk::getWorldCoords(const int& x, const int& y, const int& z) {
return glm::ivec3(mPos.x * 16 + x,
mPos.y * 16 + y,

+ 4
- 2
src/scenes/testscene.cpp View File

@@ -167,9 +167,11 @@ void TestScene::update(const float& dTime) {
std::cout << "Hit voxel at: " << hitPos.x << ", " << hitPos.y << ", " << hitPos.z << std::endl;
std::cout << "Height @ " << world.getHeight(glm::ivec2(hitPos.x + hitNormal.x, hitPos.z + hitNormal.z)) << std::endl;
if (handler.isActionDown("Place Voxel")) {
world.setVoxelType((int)(hitPos.x + hitNormal.x), (int)(hitPos.y + hitNormal.y), (int)(hitPos.z + hitNormal.z), voxelType, true);
world.placeVoxel(hitPos + hitNormal, voxelType);
//world.setVoxelType((int)(hitPos.x + hitNormal.x), (int)(hitPos.y + hitNormal.y), (int)(hitPos.z + hitNormal.z), voxelType, true);
} else {
world.setVoxelType((int)(hitPos.x), (int)(hitPos.y), (int)(hitPos.z), 0, true);
world.breakVoxel(hitPos);
//world.setVoxelType((int)(hitPos.x), (int)(hitPos.y), (int)(hitPos.z), 0, true);
}
}
} else if (!(handler.isActionDown("Place Voxel") || handler.isActionDown("Delete Voxel")) && placeVoxel) {

+ 22
- 0
src/world.cpp View File

@@ -25,6 +25,28 @@ World::World() {
mLoadThreadActive = false;
}

unsigned World::breakVoxel(const glm::ivec3& pos) {
auto chunkPos = worldPosToChunkPos(pos);
auto chunk = getChunk(chunkPos);
if (!chunk) return 0;

return chunk->breakVoxel(glm::ivec3(pos.x - (chunkPos.x * 16),
pos.y - (chunkPos.y * 16),
pos.z - (chunkPos.z * 16)));
}

bool World::placeVoxel(const glm::ivec3 &pos, const unsigned int &id) {
auto chunkPos = worldPosToChunkPos(pos);
auto chunk = getChunk(chunkPos);
if (!chunk) return 0;

return chunk->placeVoxel(glm::ivec3(pos.x - (chunkPos.x * 16),
pos.y - (chunkPos.y * 16),
pos.z - (chunkPos.z * 16)),
id);

}

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),

Loading…
Cancel
Save