voxels renderer rebuilt, WorldFiles fix

This commit is contained in:
MihailRis
2023-11-02 13:23:52 +03:00
committed by GitHub
parent 0576316282
commit 754c5b80d0
44 changed files with 1141 additions and 524 deletions
+7
View File
@@ -4,6 +4,13 @@
#define BLOCK_MODEL_CUBE 1
#define BLOCK_MODEL_X_SPRITE 2
#define FACE_MX 0
#define FACE_PX 1
#define FACE_MY 2
#define FACE_PY 3
#define FACE_MZ 4
#define FACE_PZ 5
class Block {
public:
static Block* blocks[256];
-8
View File
@@ -36,11 +36,3 @@ Chunk* Chunk::clone() const {
return other;
}
void Chunk::incref(){
references++;
}
void Chunk::decref(){
if (--references <= 0)
delete this;
}
+2 -9
View File
@@ -2,11 +2,7 @@
#define VOXELS_CHUNK_H_
#include <stdlib.h>
#define CHUNK_W 16
#define CHUNK_H 256
#define CHUNK_D 16
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D * 2)
#include "../constants.h"
#define CHUNK_MODIFIED 0x1
#define CHUNK_READY 0x2
@@ -14,7 +10,7 @@
#define CHUNK_LIGHTED 0x8
#define CHUNK_UNSAVED 0x10
class voxel;
struct voxel;
class Lightmap;
struct RenderData {
@@ -33,7 +29,6 @@ public:
Lightmap* lightmap;
int flags = 0;
int surrounding = 0;
int references = 1;
RenderData renderData;
Chunk(int x, int z);
@@ -42,8 +37,6 @@ public:
bool isEmpty();
Chunk* clone() const;
void incref();
void decref();
// flags getters/setters below
+27 -48
View File
@@ -7,29 +7,28 @@
#include "../files/WorldFiles.h"
#include "../graphics/Mesh.h"
#include "../voxmaths.h"
#include <math.h>
#include <limits.h>
using glm::vec3;
using std::shared_ptr;
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];
meshes = new Mesh*[volume];
meshesSecond = new Mesh*[volume];
chunks = new shared_ptr<Chunk>[volume];
chunksSecond = new shared_ptr<Chunk>[volume];
for (size_t i = 0; i < volume; i++){
chunks[i] = nullptr;
meshes[i] = nullptr;
}
chunksCount = 0;
}
Chunks::~Chunks(){
for (size_t i = 0; i < volume; i++){
if (chunks[i])
chunks[i]->decref();
chunks[i] = nullptr;
}
delete[] chunks;
}
@@ -45,7 +44,7 @@ voxel* Chunks::get(int x, int y, int z){
if (z < 0) cz--;
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
return nullptr;
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
shared_ptr<Chunk> chunk = chunks[(cy * d + cz) * w + cx];
if (chunk == nullptr)
return nullptr;
int lx = x - cx * CHUNK_W;
@@ -61,18 +60,15 @@ bool Chunks::isObstacle(int x, int y, int z){
return Block::blocks[v->id]->obstacle;
}
unsigned char Chunks::getLight(int x, int y, int z, int channel){
ubyte Chunks::getLight(int x, int y, int z, int channel){
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = x / CHUNK_W;
int cy = y / CHUNK_H;
int cz = z / CHUNK_D;
if (x < 0) cx--;
if (y < 0) cy--;
if (z < 0) cz--;
int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H);
int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
return 0;
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
shared_ptr<Chunk> chunk = chunks[(cy * d + cz) * w + cx];
if (chunk == nullptr)
return 0;
int lx = x - cx * CHUNK_W;
@@ -81,18 +77,15 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
return chunk->lightmap->get(lx,ly,lz, channel);
}
unsigned short Chunks::getLight(int x, int y, int z){
light_t Chunks::getLight(int x, int y, int z){
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = x / CHUNK_W;
int cy = y / CHUNK_H;
int cz = z / CHUNK_D;
if (x < 0) cx--;
if (y < 0) cy--;
if (z < 0) cz--;
int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H);
int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
return 0;
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
shared_ptr<Chunk> chunk = chunks[(cy * d + cz) * w + cx];
if (chunk == nullptr)
return 0;
int lx = x - cx * CHUNK_W;
@@ -112,7 +105,7 @@ Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
if (z < 0) cz--;
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
return nullptr;
return chunks[(cy * d + cz) * w + cx];
return chunks[(cy * d + cz) * w + cx].get();
}
Chunk* Chunks::getChunk(int x, int z){
@@ -120,7 +113,7 @@ Chunk* Chunks::getChunk(int x, int z){
z -= oz;
if (x < 0 || z < 0 || x >= w || z >= d)
return nullptr;
return chunks[z * w + x];
return chunks[z * w + x].get();
}
void Chunks::set(int x, int y, int z, int id, uint8_t states){
@@ -134,7 +127,7 @@ void Chunks::set(int x, int y, int z, int id, uint8_t states){
if (z < 0) cz--;
if (cx < 0 || cz < 0 || cx >= w || cz >= d)
return;
Chunk* chunk = chunks[cz * w + cx];
Chunk* chunk = chunks[cz * w + cx].get();
if (chunk == nullptr)
return;
int lx = x - cx * CHUNK_W;
@@ -169,7 +162,7 @@ voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, v
float stepy = (dy > 0.0f) ? 1.0f : -1.0f;
float stepz = (dz > 0.0f) ? 1.0f : -1.0f;
float infinity = std::numeric_limits<float>::infinity();
constexpr float infinity = std::numeric_limits<float>::infinity();
float txDelta = (dx == 0.0f) ? infinity : abs(1.0f / dx);
float tyDelta = (dy == 0.0f) ? infinity : abs(1.0f / dy);
@@ -256,35 +249,26 @@ void Chunks::setCenter(WorldFiles* worldFiles, int x, int z) {
void Chunks::translate(WorldFiles* worldFiles, int dx, int dz){
for (unsigned int i = 0; i < volume; i++){
chunksSecond[i] = nullptr;
meshesSecond[i] = nullptr;
}
for (int z = 0; z < d; z++){
for (int x = 0; x < w; x++){
Chunk* chunk = chunks[z * w + x];
shared_ptr<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;
worldFiles->put((const ubyte*)chunk->voxels, chunk->x, chunk->z);
chunksCount--;
continue;
}
meshesSecond[nz * w + nx] = mesh;
chunksSecond[nz * w + nx] = chunk;
}
}
Chunk** ctemp = chunks;
shared_ptr<Chunk>* ctemp = chunks;
chunks = chunksSecond;
chunksSecond = ctemp;
Mesh** mtemp = meshes;
meshes = meshesSecond;
meshesSecond = mtemp;
ox += dx;
oz += dz;
}
@@ -294,7 +278,7 @@ void Chunks::_setOffset(int x, int z){
oz = z;
}
bool Chunks::putChunk(Chunk* chunk) {
bool Chunks::putChunk(shared_ptr<Chunk> chunk) {
int x = chunk->x;
int z = chunk->z;
x -= ox;
@@ -306,14 +290,9 @@ bool Chunks::putChunk(Chunk* chunk) {
return true;
}
void Chunks::clear(bool freeMemory){
void Chunks::clear(){
for (size_t i = 0; i < volume; i++){
if (freeMemory){
chunks[i]->decref();
delete meshes[i];
}
chunks[i] = nullptr;
meshes[i] = nullptr;
}
chunksCount = 0;
}
+9 -12
View File
@@ -2,11 +2,10 @@
#define VOXELS_CHUNKS_H_
#include <stdlib.h>
#include <memory>
#include <glm/glm.hpp>
#include "../typedefs.h"
using namespace glm;
class Mesh;
class VoxelRenderer;
class Chunk;
@@ -15,10 +14,8 @@ class WorldFiles;
class Chunks {
public:
Chunk** chunks;
Chunk** chunksSecond;
Mesh** meshes;
Mesh** meshesSecond;
std::shared_ptr<Chunk>* chunks;
std::shared_ptr<Chunk>* chunksSecond;
size_t volume;
size_t chunksCount;
int w,d;
@@ -27,15 +24,15 @@ public:
Chunks(int w, int d, int ox, int oz);
~Chunks();
bool putChunk(Chunk* chunk);
bool putChunk(std::shared_ptr<Chunk> chunk);
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);
unsigned char getLight(int x, int y, int z, int channel);
light_t getLight(int x, int y, int z);
ubyte getLight(int x, int y, int z, int channel);
void set(int x, int y, int z, int id, uint8_t states);
voxel* rayCast(vec3 start, vec3 dir, float maxLength, vec3& end, vec3& norm, vec3& iend);
voxel* rayCast(glm::vec3 start, glm::vec3 dir, float maxLength, glm::vec3& end, glm::vec3& norm, glm::vec3& iend);
bool isObstacle(int x, int y, int z);
@@ -45,7 +42,7 @@ public:
void setCenter(WorldFiles* worldFiles, int x, int z);
void translate(WorldFiles* worldFiles, int x, int z);
void clear(bool freeMemory);
void clear();
};
#endif /* VOXELS_CHUNKS_H_ */
+34 -214
View File
@@ -1,14 +1,17 @@
#include "ChunksController.h"
#include "Block.h"
#include "Chunk.h"
#include "Chunks.h"
#include "ChunksStorage.h"
#include "WorldGenerator.h"
#include "../graphics/Mesh.h"
#include "../graphics/VoxelRenderer.h"
#include "../lighting/Lighting.h"
#include "../files/WorldFiles.h"
#include "ChunksLoader.h"
#include "../world/Level.h"
#include "../world/World.h"
#include <iostream>
#include <limits.h>
#include <memory>
#if defined(_WIN32) && defined(__MINGW32__)
#define _WIN32_WINNT 0x0501
@@ -19,31 +22,13 @@
#define MIN_SURROUNDING 9
using std::shared_ptr;
ChunksController::ChunksController(World* world, Chunks* chunks, Lighting* lighting) : chunks(chunks), lighting(lighting){
loadersCount = std::thread::hardware_concurrency() * 2 - 1;
if (loadersCount <= 0)
loadersCount = 1;
loaders = new ChunksLoader*[loadersCount];
for (int i = 0; i < loadersCount; i++){
loaders[i] = new ChunksLoader(world);
}
std::cout << "created " << loadersCount << " loaders" << std::endl;
ChunksController::ChunksController(Level* level, Chunks* chunks, Lighting* lighting) : level(level), chunks(chunks), lighting(lighting){
}
ChunksController::~ChunksController(){
for (int i = 0; i < loadersCount; i++)
delete loaders[i];
delete[] loaders;
}
int ChunksController::countFreeLoaders(){
int count = 0;
for (int i = 0; i < loadersCount; i++){
if (!loaders[i]->isBusy())
count++;
}
return count;
}
bool ChunksController::loadVisible(WorldFiles* worldFiles){
@@ -57,16 +42,22 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){
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];
shared_ptr<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++;
if (other != nullptr) surrounding++;
}
}
chunk->surrounding = surrounding;
if (surrounding == MIN_SURROUNDING && !chunk->isLighted()) {
lighting->buildSkyLight(chunk->x, chunk->z);
lighting->onChunkLoaded(chunk->x, chunk->z);
chunk->setLighted(true);
return false;
}
continue;
}
int lx = x - w / 2;
@@ -81,200 +72,29 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){
}
int index = nearZ * w + nearX;
Chunk* chunk = chunks->chunks[index];
if (chunk != nullptr)
shared_ptr<Chunk> chunk = chunks->chunks[index];
if (chunk != nullptr) {
return false;
}
ChunksLoader* freeLoader = getFreeLoader();
if (freeLoader == nullptr)
return false;
chunk = new Chunk(nearX+ox, nearZ+oz);
if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels))
chunk = shared_ptr<Chunk>(new Chunk(nearX+ox, nearZ+oz));
level->chunksStorage->store(chunk);
if (worldFiles->getChunk(chunk->x, chunk->z, (ubyte*)chunk->voxels))
chunk->setLoaded(true);
chunks->putChunk(chunk);
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->isReady())
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;
if (!chunk->isLoaded()) {
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->z, level->world->seed);
chunk->setUnsaved(true);
}
freeLoader->load(chunk, (Chunk**)closes);
for (size_t i = 0; i < CHUNK_VOL; i++) {
if (Block::blocks[chunk->voxels[i].id] == nullptr) {
std::cout << "corruped block detected at " << i << " of chunk " << chunk->x << "x" << chunk->z << std::endl;
chunk->voxels[i].id = 11;
}
}
lighting->prebuildSkyLight(chunk->x, chunk->z);
return true;
}
ChunksLoader* ChunksController::getFreeLoader() {
ChunksLoader* freeLoader = nullptr;
for (int i = 0; i < loadersCount; i++){
ChunksLoader* loader = loaders[i];
if (loader->isBusy()){
continue;
}
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() {
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 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;
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 = nearZ * w + nearX;
Chunk* chunk = chunks->chunks[index];
if (chunk == nullptr){
return false;
}
Mesh* mesh = chunks->meshes[index];
if (mesh == nullptr || chunk->isModified()){
if (chunk->renderData.vertices != nullptr) {
return false;
}
Chunk* closes[9];
if (chunk->isEmpty()){
chunks->meshes[index] = nullptr;
return false;
}
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;
if ((!other->isReady() || !other->isLighted()) && other != chunk)
return false;
closes[oz * 3 + ox] = other;
}
chunk->setModified(false);
chunk->renderData.vertices = (float*)1;
freeLoader->render(chunk, (Chunk**)closes);
return true;
}
return false;
}
}
+3 -8
View File
@@ -1,7 +1,7 @@
#ifndef VOXELS_CHUNKSCONTROLLER_H_
#define VOXELS_CHUNKSCONTROLLER_H_
class World;
class Level;
class Chunks;
class Lighting;
class WorldFiles;
@@ -10,19 +10,14 @@ class ChunksLoader;
class ChunksController {
private:
Level* level;
Chunks* chunks;
Lighting* lighting;
ChunksLoader** loaders;
int loadersCount;
public:
ChunksController(World* world, Chunks* chunks, Lighting* lighting);
ChunksController(Level* level, Chunks* chunks, Lighting* lighting);
~ChunksController();
ChunksLoader* getFreeLoader();
int countFreeLoaders();
bool loadVisible(WorldFiles* worldFiles);
void calculateLights();
bool _buildMeshes();
};
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */
+93
View File
@@ -0,0 +1,93 @@
#include "ChunksStorage.h"
#include <assert.h>
#include "VoxelsVolume.h"
#include "Chunk.h"
#include "../voxmaths.h"
#include "../lighting/Lightmap.h"
using glm::ivec2;
using std::shared_ptr;
ChunksStorage::ChunksStorage() {
}
ChunksStorage::~ChunksStorage() {
}
void ChunksStorage::store(shared_ptr<Chunk> chunk) {
chunksMap[ivec2(chunk->x, chunk->z)] = chunk;
}
shared_ptr<Chunk> ChunksStorage::get(int x, int z) const {
auto found = chunksMap.find(ivec2(x, z));
if (found == chunksMap.end()) {
return nullptr;
}
return found->second;
}
// some magic code
void ChunksStorage::getVoxels(VoxelsVolume* volume) const {
voxel* voxels = volume->getVoxels();
light_t* lights = volume->getLights();
int x = volume->getX();
int y = volume->getY();
int z = volume->getZ();
int w = volume->getW();
int h = volume->getH();
int d = volume->getD();
int scx = floordiv(x, CHUNK_W);
int scz = floordiv(z, CHUNK_D);
int ecx = floordiv(x + w, CHUNK_W);
int ecz = floordiv(z + d, CHUNK_D);
int cw = ecx - scx + 1;
int ch = ecz - scz + 1;
// cw*ch chunks will be scanned
for (int cz = scz; cz < scz + ch; cz++) {
for (int cx = scx; cx < scx + cw; cx++) {
auto found = chunksMap.find(ivec2(cx, cz));
if (found == chunksMap.end()) {
// no chunk loaded -> filling with BLOCK_VOID
for (int ly = y; ly < y + h; ly++) {
for (int lz = max(z, cz * CHUNK_D);
lz < min(z + d, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = max(x, cx * CHUNK_W);
lx < min(x + w, (cx + 1) * CHUNK_W);
lx++) {
voxels[vox_index(lx - x, ly - y, lz - z, w, d)].id = BLOCK_VOID;
lights[vox_index(lx - x, ly - y, lz - z, w, d)] = 0;
}
}
}
}
else {
const std::shared_ptr<Chunk>& chunk = found->second;
const voxel* cvoxels = chunk->voxels;
const light_t* clights = chunk->lightmap->getLights();
for (int ly = y; ly < y + h; ly++) {
for (int lz = max(z, cz * CHUNK_D);
lz < min(z + d, (cz + 1) * CHUNK_D);
lz++) {
for (int lx = max(x, cx * CHUNK_W);
lx < min(x + w, (cx + 1) * CHUNK_W);
lx++) {
voxels[vox_index(lx - x, ly - y, lz - z, w, d)] =
cvoxels[vox_index(lx - cx * CHUNK_W, ly, lz - cz * CHUNK_D, CHUNK_W, CHUNK_D)];
lights[vox_index(lx - x, ly - y, lz - z, w, d)] =
clights[vox_index(lx - cx * CHUNK_W, ly, lz - cz * CHUNK_D, CHUNK_W, CHUNK_D)];
}
}
}
}
}
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef VOXELS_CHUNKSSTORAGE_H_
#define VOXELS_CHUNKSSTORAGE_H_
#include <memory>
#include <unordered_map>
#include "voxel.h"
#include "../typedefs.h"
#define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp"
class Chunk;
class VoxelsVolume;
class ChunksStorage {
std::unordered_map<glm::ivec2, std::shared_ptr<Chunk>> chunksMap;
public:
ChunksStorage();
virtual ~ChunksStorage();
std::shared_ptr<Chunk> get(int x, int y) const;
void store(std::shared_ptr<Chunk> chunk);
void getVoxels(VoxelsVolume* volume) const;
light_t getLight(int x, int y, int z, ubyte channel) const;
};
#endif // VOXELS_CHUNKSSTORAGE_H_
+30
View File
@@ -0,0 +1,30 @@
#include "VoxelsVolume.h"
VoxelsVolume::VoxelsVolume(int x, int y, int z, int w, int h, int d)
: x(x), y(y), z(z), w(w), h(h), d(d) {
voxels = new voxel[w * h * d];
for (int i = 0; i < w * h * d; i++) {
voxels[i].id = BLOCK_VOID;
}
lights = new light_t[w * h * d];
}
VoxelsVolume::VoxelsVolume(int w, int h, int d)
: x(0), y(0), z(0), w(w), h(h), d(d) {
voxels = new voxel[w * h * d];
for (int i = 0; i < w * h * d; i++) {
voxels[i].id = BLOCK_VOID;
}
lights = new light_t[w * h * d];
}
VoxelsVolume::~VoxelsVolume() {
delete[] lights;
delete[] voxels;
}
void VoxelsVolume::setPosition(int x, int y, int z) {
this->x = x;
this->y = y;
this->z = z;
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef VOXELS_VOXELSVOLUME_H_
#define VOXELS_VOXELSVOLUME_H_
#include "../typedefs.h"
#include "../constants.h"
#include "voxel.h"
class VoxelsVolume {
int x, y, z;
int w, h, d;
voxel* voxels;
light_t* lights;
public:
VoxelsVolume(int w, int h, int d);
VoxelsVolume(int x, int y, int z, int w, int h, int d);
virtual ~VoxelsVolume();
void setPosition(int x, int y, int z);
int getX() const {
return x;
}
int getY() const {
return y;
}
int getZ() const {
return z;
}
int getW() const {
return w;
}
int getH() const {
return h;
}
int getD() const {
return d;
}
voxel* getVoxels() const {
return voxels;
}
light_t* getLights() const {
return lights;
}
inline blockid_t pickBlockId(int bx, int by, int bz) const {
if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) {
return BLOCK_VOID;
}
return voxels[vox_index(bx - x, by - y, bz - z, w, d)].id;
}
inline light_t pickLight(int bx, int by, int bz) const {
if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) {
return 0;
}
return lights[vox_index(bx - x, by - y, bz - z, w, d)];
}
};
#endif // VOXELS_VOXELSVOLUME_H_
+2 -2
View File
@@ -1,10 +1,10 @@
#ifndef VOXELS_VOXEL_H_
#define VOXELS_VOXEL_H_
#include <stdint.h>
#include "../typedefs.h"
struct voxel {
uint8_t id;
blockid_t id;
uint8_t states;
};