format: reformat project

Signed-off-by: Vyacheslav Ivanov <islavaivanov76@gmail.com>
This commit is contained in:
Vyacheslav Ivanov
2024-08-03 19:53:48 +03:00
committed by Pugemon
parent 736cd175d5
commit bbf33e8e4d
202 changed files with 7389 additions and 5609 deletions
+54 -38
View File
@@ -7,12 +7,18 @@
std::string to_string(BlockModel model) {
switch (model) {
case BlockModel::none: return "none";
case BlockModel::block: return "block";
case BlockModel::xsprite: return "X";
case BlockModel::aabb: return "aabb";
case BlockModel::custom: return "custom";
default: return "unknown";
case BlockModel::none:
return "none";
case BlockModel::block:
return "block";
case BlockModel::xsprite:
return "X";
case BlockModel::aabb:
return "aabb";
case BlockModel::custom:
return "custom";
default:
return "unknown";
}
}
@@ -32,8 +38,7 @@ std::optional<BlockModel> BlockModel_from(std::string_view str) {
}
CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ)
: axisX(axisX), axisY(axisY), axisZ(axisZ)
{
: axisX(axisX), axisY(axisY), axisZ(axisZ) {
fix = glm::ivec3(0);
if (isVectorHasNegatives(axisX)) fix -= axisX;
if (isVectorHasNegatives(axisY)) fix -= axisY;
@@ -50,39 +55,50 @@ void CoordSystem::transform(AABB& aabb) const {
aabb.b += fix;
}
const BlockRotProfile BlockRotProfile::NONE {"none", {
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // North
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // East
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // South
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // West
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Down
}};
const BlockRotProfile BlockRotProfile::NONE {
"none",
{
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // North
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // East
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // South
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // West
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Down
}};
const BlockRotProfile BlockRotProfile::PIPE {
"pipe",
{
{{1, 0, 0}, {0, 0, 1}, {0, -1, 0}}, // North
{{0, 0, 1}, {-1, 0, 0}, {0, -1, 0}}, // East
{{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}, // South
{{0, 0, -1}, {1, 0, 0}, {0, -1, 0}}, // West
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // Up
{{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, // Down
}};
const BlockRotProfile BlockRotProfile::PIPE {"pipe", {
{ { 1, 0, 0 }, { 0, 0, 1 }, { 0, -1, 0 }}, // North
{ { 0, 0, 1 }, {-1, 0, 0 }, { 0, -1, 0 }}, // East
{ {-1, 0, 0 }, { 0, 0,-1 }, { 0, -1, 0 }}, // South
{ { 0, 0,-1 }, { 1, 0, 0 }, { 0, -1, 0 }}, // West
{ { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }}, // Up
{ { 1, 0, 0 }, { 0,-1, 0 }, { 0, 0,-1 }}, // Down
}};
const BlockRotProfile BlockRotProfile::PANE {"pane", {
{ { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }}, // North
{ { 0, 0,-1 }, { 0, 1, 0 }, { 1, 0, 0 }}, // East
{ {-1, 0, 0 }, { 0, 1, 0 }, { 0, 0,-1 }}, // South
{ { 0, 0, 1 }, { 0, 1, 0 }, {-1, 0, 0 }}, // West
}};
const BlockRotProfile BlockRotProfile::PANE {
"pane",
{
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // North
{{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East
{{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South
{{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West
}};
Block::Block(const std::string& name)
: name(name),
: name(name),
caption(util::id_to_caption(name)),
textureFaces {TEXTURE_NOTFOUND,TEXTURE_NOTFOUND,TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,TEXTURE_NOTFOUND,TEXTURE_NOTFOUND}
{}
textureFaces {
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND,
TEXTURE_NOTFOUND} {
}
Block::Block(std::string name, const std::string& texture) : name(std::move(name)),
textureFaces{texture,texture,texture,texture,texture,texture}
{}
Block::Block(std::string name, const std::string& texture)
: name(std::move(name)),
textureFaces {texture, texture, texture, texture, texture, texture} {
}
+46 -44
View File
@@ -1,13 +1,13 @@
#ifndef VOXELS_BLOCK_HPP_
#define VOXELS_BLOCK_HPP_
#include <glm/glm.hpp>
#include <optional>
#include <string>
#include <vector>
#include <optional>
#include <glm/glm.hpp>
#include "../maths/aabb.hpp"
#include "../maths/UVRegion.hpp"
#include "../maths/aabb.hpp"
#include "../typedefs.hpp"
inline std::string BLOCK_ITEM_SUFFIX = ".item";
@@ -26,13 +26,13 @@ inline constexpr uint BLOCK_AABB_GRID = 16;
inline std::string DEFAULT_MATERIAL = "base:stone";
struct block_funcs_set {
bool init: 1;
bool update: 1;
bool onplaced: 1;
bool onbroken: 1;
bool oninteract: 1;
bool randupdate: 1;
bool onblockstick: 1;
bool init : 1;
bool update : 1;
bool onplaced : 1;
bool onbroken : 1;
bool oninteract : 1;
bool randupdate : 1;
bool onblockstick : 1;
};
struct CoordSystem {
@@ -89,7 +89,6 @@ std::optional<BlockModel> BlockModel_from(std::string_view str);
using BoxModel = AABB;
/// @brief Common kit of block properties applied to groups of blocks
struct BlockMaterial {
std::string name;
@@ -105,32 +104,34 @@ public:
std::string const name;
std::string caption;
/// @brief Textures set applied to block sides
std::string textureFaces[6]; // -x,x, -y,y, -z,z
std::string textureFaces[6]; // -x,x, -y,y, -z,z
std::vector<std::string> modelTextures = {};
std::vector<BoxModel> modelBoxes = {};
std::vector<glm::vec3> modelExtraPoints = {}; //initially made for tetragons
std::vector<UVRegion> modelUVs = {}; // boxes' tex-UVs also there
std::vector<glm::vec3> modelExtraPoints =
{}; // initially made for tetragons
std::vector<UVRegion> modelUVs = {}; // boxes' tex-UVs also there
/// @brief id of used BlockMaterial, may specify non-existing material
std::string material = DEFAULT_MATERIAL;
/// @brief Light emission R, G, B, S (sky lights: sun, moon, radioactive clouds)
/// @brief Light emission R, G, B, S (sky lights: sun, moon, radioactive
/// clouds)
uint8_t emission[4] {0, 0, 0, 0};
glm::i8vec3 size {1, 1, 1};
/// @brief Influences visible block sides for transparent blocks
uint8_t drawGroup = 0;
/// @brief Block model type
BlockModel model = BlockModel::block;
/// @brief Does the block passing lights into itself
bool lightPassing = false;
/// @brief Does the block passing top-down sky lights into itself
bool skyLightPassing = false;
@@ -139,70 +140,71 @@ public:
/// @brief Does block model have vertex-based AO effect
bool ambientOcclusion = true;
/// @brief Is the block a physical obstacle
bool obstacle = true;
/// @brief Can the block be selected
bool selectable = true;
/// @brief Can the block be replaced with other.
/// @brief Can the block be replaced with other.
/// Examples of replaceable blocks: air, flower, water
bool replaceable = false;
/// @brief Can player destroy the block
bool breakable = true;
/// @brief Can the block be oriented different ways
bool rotatable = false;
/// @brief Can the block exist without physical support be a solid block below
/// @brief Can the block exist without physical support be a solid block
/// below
bool grounded = false;
/// @brief Turns off block item generation
bool hidden = false;
/// @brief Set of block physical hitboxes
std::vector<AABB> hitboxes;
/// @brief Set of available block rotations (coord-systems)
BlockRotProfile rotations = BlockRotProfile::NONE;
/// @brief Item will be picked on MMB click on the block
std::string pickingItem = name+BLOCK_ITEM_SUFFIX;
std::string pickingItem = name + BLOCK_ITEM_SUFFIX;
/// @brief Block script name in blocks/ without extension
std::string scriptName = name.substr(name.find(':')+1);
std::string scriptName = name.substr(name.find(':') + 1);
/// @brief Default block layout will be used by hud.open_block(...)
std::string uiLayout = name;
/// @brief Block inventory size. 0 - no inventory
uint inventorySize = 0;
// @brief Block tick interval (1 - 20tps, 2 - 10tps)
uint tickInterval = 1;
uint tickInterval = 1;
/// @brief Runtime indices (content indexing results)
struct {
/// @brief block runtime integer id
blockid_t id;
/// @brief is the block completely opaque for render and raycast
bool solid = true;
/// @brief does the block emit any lights
bool emissive = false;
// @brief block size is greather than 1x1x1
bool extended = false;
/// @brief set of hitboxes sets with all coord-systems precalculated
std::vector<AABB> hitboxes[BlockRotProfile::MAX_COUNT];
/// @brief set of block callbacks flags
block_funcs_set funcsset {};
/// @brief picking item integer id
itemid_t pickingItem = 0;
} rt {};
@@ -216,4 +218,4 @@ inline glm::ivec3 get_ground_direction(const Block* def, int rotation) {
return -def->rotations.variants[rotation].axisY;
}
#endif // VOXELS_BLOCK_HPP_
#endif // VOXELS_BLOCK_HPP_
+30 -28
View File
@@ -2,21 +2,20 @@
#include <utility>
#include "../content/ContentLUT.hpp"
#include "../items/Inventory.hpp"
#include "../lighting/Lightmap.hpp"
#include "voxel.hpp"
#include "../items/Inventory.hpp"
#include "../content/ContentLUT.hpp"
#include "../lighting/Lightmap.hpp"
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos){
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) {
bottom = 0;
top = CHUNK_H;
}
bool Chunk::isEmpty(){
bool Chunk::isEmpty() {
int id = -1;
for (uint i = 0; i < CHUNK_VOL; i++){
if (voxels[i].id != id){
for (uint i = 0; i < CHUNK_VOL; i++) {
if (voxels[i].id != id) {
if (id != -1)
return false;
else
@@ -41,8 +40,9 @@ void Chunk::updateHeights() {
}
}
void Chunk::addBlockInventory(std::shared_ptr<Inventory> inventory,
uint x, uint y, uint z) {
void Chunk::addBlockInventory(
std::shared_ptr<Inventory> inventory, uint x, uint y, uint z
) {
inventories[vox_index(x, y, z)] = std::move(inventory);
flags.unsaved = true;
}
@@ -57,9 +57,9 @@ void Chunk::setBlockInventories(chunk_inventories_map map) {
inventories = std::move(map);
}
std::shared_ptr<Inventory> Chunk::getBlockInventory(uint x, uint y, uint z) const {
if (x >= CHUNK_W || y >= CHUNK_H || z >= CHUNK_D)
return nullptr;
std::shared_ptr<Inventory> Chunk::getBlockInventory(uint x, uint y, uint z)
const {
if (x >= CHUNK_W || y >= CHUNK_H || z >= CHUNK_D) return nullptr;
const auto& found = inventories.find(vox_index(x, y, z));
if (found == inventories.end()) {
return nullptr;
@@ -68,7 +68,7 @@ std::shared_ptr<Inventory> Chunk::getBlockInventory(uint x, uint y, uint z) cons
}
std::unique_ptr<Chunk> Chunk::clone() const {
auto other = std::make_unique<Chunk>(x,z);
auto other = std::make_unique<Chunk>(x, z);
for (uint i = 0; i < CHUNK_VOL; i++) {
other->voxels[i] = voxels[i];
}
@@ -76,7 +76,7 @@ std::unique_ptr<Chunk> Chunk::clone() const {
return other;
}
/**
/**
Current chunk format:
- byte-order: big-endian
- [don't panic!] first and second bytes are separated for RLE efficiency
@@ -94,11 +94,11 @@ std::unique_ptr<ubyte[]> Chunk::encode() const {
auto buffer = std::make_unique<ubyte[]>(CHUNK_DATA_LEN);
for (uint i = 0; i < CHUNK_VOL; i++) {
buffer[i] = voxels[i].id >> 8;
buffer[CHUNK_VOL+i] = voxels[i].id & 0xFF;
buffer[CHUNK_VOL + i] = voxels[i].id & 0xFF;
blockstate_t state = blockstate2int(voxels[i].state);
buffer[CHUNK_VOL*2 + i] = state >> 8;
buffer[CHUNK_VOL*3 + i] = state & 0xFF;
buffer[CHUNK_VOL * 2 + i] = state >> 8;
buffer[CHUNK_VOL * 3 + i] = state & 0xFF;
}
return buffer;
}
@@ -109,15 +109,16 @@ bool Chunk::decode(const ubyte* data) {
ubyte bid1 = data[i];
ubyte bid2 = data[CHUNK_VOL + i];
ubyte bst1 = data[CHUNK_VOL*2 + i];
ubyte bst2 = data[CHUNK_VOL*3 + i];
vox.id = (static_cast<blockid_t>(bid1) << 8) |
static_cast<blockid_t>(bid2);
ubyte bst1 = data[CHUNK_VOL * 2 + i];
ubyte bst2 = data[CHUNK_VOL * 3 + i];
vox.id =
(static_cast<blockid_t>(bid1) << 8) | static_cast<blockid_t>(bid2);
vox.state = int2blockstate(
(static_cast<blockstate_t>(bst1) << 8) |
static_cast<blockstate_t>(bst2));
(static_cast<blockstate_t>(bst1) << 8) |
static_cast<blockstate_t>(bst2)
);
}
return true;
}
@@ -125,10 +126,11 @@ bool Chunk::decode(const ubyte* data) {
void Chunk::convert(ubyte* data, const ContentLUT* lut) {
for (uint i = 0; i < CHUNK_VOL; i++) {
// see encode method to understand what the hell is going on here
blockid_t id = ((static_cast<blockid_t>(data[i]) << 8) |
static_cast<blockid_t>(data[CHUNK_VOL+i]));
blockid_t id =
((static_cast<blockid_t>(data[i]) << 8) |
static_cast<blockid_t>(data[CHUNK_VOL + i]));
blockid_t replacement = lut->blocks.getId(id);
data[i] = replacement >> 8;
data[CHUNK_VOL+i] = replacement & 0xFF;
data[CHUNK_VOL + i] = replacement & 0xFF;
}
}
+13 -12
View File
@@ -1,16 +1,16 @@
#ifndef VOXELS_CHUNK_HPP_
#define VOXELS_CHUNK_HPP_
#include <memory>
#include <stdlib.h>
#include <unordered_map>
#include "voxel.hpp"
#include <memory>
#include <unordered_map>
#include "../constants.hpp"
#include "../lighting/Lightmap.hpp"
#include "voxel.hpp"
inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4;
inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL * 4;
class Lightmap;
class ContentLUT;
@@ -20,7 +20,8 @@ namespace dynamic {
class Map;
}
using chunk_inventories_map = std::unordered_map<uint, std::shared_ptr<Inventory>>;
using chunk_inventories_map =
std::unordered_map<uint, std::shared_ptr<Inventory>>;
class Chunk {
public:
@@ -29,13 +30,13 @@ public:
voxel voxels[CHUNK_VOL] {};
Lightmap lightmap;
struct {
bool modified: 1;
bool ready: 1;
bool loaded: 1;
bool lighted: 1;
bool unsaved: 1;
bool loadedLights: 1;
bool entities: 1;
bool modified : 1;
bool ready : 1;
bool loaded : 1;
bool lighted : 1;
bool unsaved : 1;
bool loadedLights : 1;
bool entities : 1;
} flags {};
/// @brief Block inventories map where key is index of block in voxels array
+142 -111
View File
@@ -1,44 +1,51 @@
#include "Chunks.hpp"
#include "Chunk.hpp"
#include "voxel.hpp"
#include "Block.hpp"
#include "WorldGenerator.hpp"
#include "../content/Content.hpp"
#include "../lighting/Lightmap.hpp"
#include "../files/WorldFiles.hpp"
#include "../world/LevelEvents.hpp"
#include "../world/Level.hpp"
#include "../objects/Entities.hpp"
#include "../graphics/core/Mesh.hpp"
#include "../maths/voxmaths.hpp"
#include "../maths/aabb.hpp"
#include "../maths/rays.hpp"
#include <limits.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include "../coders/byte_utils.hpp"
#include "../coders/json.hpp"
#include <math.h>
#include <limits.h>
#include <vector>
#include <algorithm>
#include "../content/Content.hpp"
#include "../files/WorldFiles.hpp"
#include "../graphics/core/Mesh.hpp"
#include "../lighting/Lightmap.hpp"
#include "../maths/aabb.hpp"
#include "../maths/rays.hpp"
#include "../maths/voxmaths.hpp"
#include "../objects/Entities.hpp"
#include "../world/Level.hpp"
#include "../world/LevelEvents.hpp"
#include "Block.hpp"
#include "Chunk.hpp"
#include "WorldGenerator.hpp"
#include "voxel.hpp"
Chunks::Chunks(
uint32_t w, uint32_t d,
int32_t ox, int32_t oz,
uint32_t w,
uint32_t d,
int32_t ox,
int32_t oz,
WorldFiles* wfile,
Level* level
) : level(level),
indices(level->content->getIndices()),
chunks(w*d),
chunksSecond(w*d),
w(w), d(d), ox(ox), oz(oz),
worldFiles(wfile)
{
volume = static_cast<size_t>(w)*static_cast<size_t>(d);
)
: level(level),
indices(level->content->getIndices()),
chunks(w * d),
chunksSecond(w * d),
w(w),
d(d),
ox(ox),
oz(oz),
worldFiles(wfile) {
volume = static_cast<size_t>(w) * static_cast<size_t>(d);
chunksCount = 0;
}
voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const {
x -= ox * CHUNK_W;
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W);
int cy = floordiv(y, CHUNK_H);
@@ -46,7 +53,7 @@ voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const {
if (cx < 0 || cy < 0 || cz < 0 || cx >= int(w) || cy >= 1 || cz >= int(d)) {
return nullptr;
}
auto& chunk = chunks[cz * w + cx]; // not thread safe
auto& chunk = chunks[cz * w + cx]; // not thread safe
if (chunk == nullptr) {
return nullptr;
}
@@ -56,7 +63,7 @@ voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const {
return &chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx];
}
const AABB* Chunks::isObstacleAt(float x, float y, float z){
const AABB* Chunks::isObstacleAt(float x, float y, float z) {
int ix = floor(x);
int iy = floor(y);
int iz = floor(z);
@@ -76,11 +83,12 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
glm::ivec3 point(ix, iy, iz);
offset = seekOrigin(point, def, v->state) - point;
}
const auto& boxes = def->rotatable
? def->rt.hitboxes[v->state.rotation]
: def->hitboxes;
const auto& boxes = def->rotatable ? def->rt.hitboxes[v->state.rotation]
: def->hitboxes;
for (const auto& hitbox : boxes) {
if (hitbox.contains({x - ix - offset.x, y - iy - offset.y, z - iz - offset.z})) {
if (hitbox.contains(
{x - ix - offset.x, y - iy - offset.y, z - iz - offset.z}
)) {
return &hitbox;
}
}
@@ -90,26 +98,23 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){
bool Chunks::isSolidBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr)
return false;
if (v == nullptr) return false;
return indices->blocks.get(v->id)->rt.solid;
}
bool Chunks::isReplaceableBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr)
return false;
if (v == nullptr) return false;
return indices->blocks.get(v->id)->replaceable;
}
bool Chunks::isObstacleBlock(int32_t x, int32_t y, int32_t z) {
voxel* v = get(x, y, z);
if (v == nullptr)
return false;
if (v == nullptr) return false;
return indices->blocks.get(v->id)->obstacle;
}
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){
ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) {
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W);
@@ -128,7 +133,7 @@ ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel){
return chunk->lightmap.get(lx, ly, lz, channel);
}
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z){
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) {
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W);
@@ -144,31 +149,32 @@ light_t Chunks::getLight(int32_t x, int32_t y, int32_t z){
int lx = x - cx * CHUNK_W;
int ly = y - cy * CHUNK_H;
int lz = z - cz * CHUNK_D;
return chunk->lightmap.get(lx,ly,lz);
return chunk->lightmap.get(lx, ly, lz);
}
Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) {
if (y < 0 || y >= CHUNK_H)
return nullptr;
if (y < 0 || y >= CHUNK_H) return nullptr;
x -= ox * CHUNK_W;
z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d))
return nullptr;
if (cx < 0 || cz < 0 || cx >= int(w) || cz >= int(d)) return nullptr;
return chunks[cz * w + cx].get();
}
Chunk* Chunks::getChunk(int x, int z){
Chunk* Chunks::getChunk(int x, int z) {
x -= ox;
z -= oz;
if (x < 0 || z < 0 || x >= static_cast<int>(w) || z >= static_cast<int>(d)) {
if (x < 0 || z < 0 || x >= static_cast<int>(w) ||
z >= static_cast<int>(d)) {
return nullptr;
}
return chunks[z * w + x].get();
}
glm::ivec3 Chunks::seekOrigin(glm::ivec3 pos, const Block* def, blockstate state) {
glm::ivec3 Chunks::seekOrigin(
glm::ivec3 pos, const Block* def, blockstate state
) {
const auto& rotation = def->rotations.variants[state.rotation];
auto segment = state.segment;
while (true) {
@@ -187,7 +193,9 @@ glm::ivec3 Chunks::seekOrigin(glm::ivec3 pos, const Block* def, blockstate state
}
}
void Chunks::eraseSegments(const Block* def, blockstate state, int x, int y, int z) {
void Chunks::eraseSegments(
const Block* def, blockstate state, int x, int y, int z
) {
const auto& rotation = def->rotations.variants[state.rotation];
for (int sy = 0; sy < def->size.y; sy++) {
for (int sz = 0; sz < def->size.z; sz++) {
@@ -209,7 +217,9 @@ static constexpr uint8_t segment_to_int(int sx, int sy, int sz) {
return ((sx > 0) | ((sy > 0) << 1) | ((sz > 0) << 2));
}
void Chunks::repairSegments(const Block* def, blockstate state, int x, int y, int z) {
void Chunks::repairSegments(
const Block* def, blockstate state, int x, int y, int z
) {
const auto& rotation = def->rotations.variants[state.rotation];
const auto id = def->rt.id;
const auto size = def->size;
@@ -232,7 +242,9 @@ void Chunks::repairSegments(const Block* def, blockstate state, int x, int y, in
}
}
bool Chunks::checkReplaceability(const Block* def, blockstate state, glm::ivec3 origin, blockid_t ignore) {
bool Chunks::checkReplaceability(
const Block* def, blockstate state, glm::ivec3 origin, blockid_t ignore
) {
const auto& rotation = def->rotations.variants[state.rotation];
const auto size = def->size;
for (int sy = 0; sy < size.y; sy++) {
@@ -261,7 +273,7 @@ void Chunks::setRotationExtended(
) {
auto newstate = state;
newstate.rotation = index;
// unable to rotate block (cause: obstacles)
if (!checkReplaceability(def, newstate, origin, def->rt.id)) {
return;
@@ -281,7 +293,7 @@ void Chunks::setRotationExtended(
blockstate segState = newstate;
segState.segment = segment_to_int(sx, sy, sz);
auto vox = get(pos);
// checked for nullptr by checkReplaceability
if (vox->id != def->rt.id) {
@@ -303,7 +315,9 @@ void Chunks::setRotationExtended(
pos += prevRotation.axisX * sx;
pos += prevRotation.axisY * sy;
pos += prevRotation.axisZ * sz;
if (std::find(segmentBlocks.begin(), segmentBlocks.end(), pos) == segmentBlocks.end()) {
if (std::find(
segmentBlocks.begin(), segmentBlocks.end(), pos
) == segmentBlocks.end()) {
set(pos.x, pos.y, pos.z, 0, {});
}
}
@@ -328,11 +342,13 @@ void Chunks::setRotation(int32_t x, int32_t y, int32_t z, uint8_t index) {
} else {
vox->state.rotation = index;
auto chunk = getChunkByVoxel(x, y, z);
chunk->setModifiedAndUnsaved();
chunk->setModifiedAndUnsaved();
}
}
void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) {
void Chunks::set(
int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state
) {
if (y < 0 || y >= CHUNK_H) {
return;
}
@@ -342,7 +358,8 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
z -= oz * CHUNK_D;
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
if (cx < 0 || cz < 0 || cx >= static_cast<int>(w) || cz >= static_cast<int>(d)) {
if (cx < 0 || cz < 0 || cx >= static_cast<int>(w) ||
cz >= static_cast<int>(d)) {
return;
}
Chunk* chunk = chunks[cz * w + cx].get();
@@ -351,9 +368,9 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
}
int lx = x - cx * CHUNK_W;
int lz = z - cz * CHUNK_D;
// block finalization
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
auto prevdef = indices->blocks.get(vox.id);
if (prevdef->inventorySize == 0) {
chunk->removeBlockInventory(lx, y, lz);
@@ -371,27 +388,30 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
repairSegments(newdef, state, gx, y, gz);
}
if (y < chunk->bottom) chunk->bottom = y;
else if (y + 1 > chunk->top) chunk->top = y + 1;
else if (id == 0) chunk->updateHeights();
if (y < chunk->bottom)
chunk->bottom = y;
else if (y + 1 > chunk->top)
chunk->top = y + 1;
else if (id == 0)
chunk->updateHeights();
if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz)))
if (lx == 0 && (chunk = getChunk(cx + ox - 1, cz + oz)))
chunk->flags.modified = true;
if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1)))
if (lz == 0 && (chunk = getChunk(cx + ox, cz + oz - 1)))
chunk->flags.modified = true;
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz)))
if (lx == CHUNK_W - 1 && (chunk = getChunk(cx + ox + 1, cz + oz)))
chunk->flags.modified = true;
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1)))
if (lz == CHUNK_D - 1 && (chunk = getChunk(cx + ox, cz + oz + 1)))
chunk->flags.modified = true;
}
voxel* Chunks::rayCast(
glm::vec3 start,
glm::vec3 dir,
float maxDist,
glm::vec3& end,
glm::ivec3& norm,
glm::vec3 start,
glm::vec3 dir,
float maxDist,
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend
) {
float px = start.x;
@@ -425,11 +445,11 @@ voxel* Chunks::rayCast(
float tyMax = (tyDelta < infinity) ? tyDelta * ydist : infinity;
float tzMax = (tzDelta < infinity) ? tzDelta * zdist : infinity;
int steppedIndex = -1;
while (t <= maxDist) {
voxel* voxel = get(ix, iy, iz);
if (voxel == nullptr){
int steppedIndex = -1;
while (t <= maxDist) {
voxel* voxel = get(ix, iy, iz);
if (voxel == nullptr) {
return nullptr;
}
const auto def = indices->blocks.get(voxel->id);
@@ -440,11 +460,11 @@ voxel* Chunks::rayCast(
iend.x = ix;
iend.y = iy;
iend.z = iz;
if (!def->rt.solid) {
const std::vector<AABB>& hitboxes = def->rotatable
? def->rt.hitboxes[voxel->state.rotation]
: def->hitboxes;
const std::vector<AABB>& hitboxes =
def->rotatable ? def->rt.hitboxes[voxel->state.rotation]
: def->hitboxes;
scalar_t distance = maxDist;
Ray ray(start, dir);
@@ -461,7 +481,9 @@ voxel* Chunks::rayCast(
box.b += offset;
scalar_t boxDistance;
glm::ivec3 boxNorm;
if (ray.intersectAABB(iend, box, maxDist, boxNorm, boxDistance) > RayRelation::None &&
if (ray.intersectAABB(
iend, box, maxDist, boxNorm, boxDistance
) > RayRelation::None &&
boxDistance < distance) {
hit = true;
distance = boxDistance;
@@ -520,7 +542,9 @@ voxel* Chunks::rayCast(
return nullptr;
}
glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist) {
glm::vec3 Chunks::rayCastToObstacle(
glm::vec3 start, glm::vec3 dir, float maxDist
) {
const float px = start.x;
const float py = start.y;
const float pz = start.z;
@@ -558,9 +582,9 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
const auto def = indices->blocks.get(voxel->id);
if (def->obstacle) {
if (!def->rt.solid) {
const std::vector<AABB>& hitboxes = def->rotatable
? def->rt.hitboxes[voxel->state.rotation]
: def->modelBoxes;
const std::vector<AABB>& hitboxes =
def->rotatable ? def->rt.hitboxes[voxel->state.rotation]
: def->modelBoxes;
scalar_t distance;
glm::ivec3 norm;
@@ -568,17 +592,23 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
glm::ivec3 offset {};
if (voxel->state.segment) {
offset = seekOrigin({ix, iy, iz}, def, voxel->state) - glm::ivec3(ix, iy, iz);
offset = seekOrigin({ix, iy, iz}, def, voxel->state) -
glm::ivec3(ix, iy, iz);
}
for (const auto& box : hitboxes) {
// norm is dummy now, can be inefficient
if (ray.intersectAABB(glm::ivec3(ix, iy, iz)+offset, box, maxDist, norm, distance) > RayRelation::None) {
if (ray.intersectAABB(
glm::ivec3(ix, iy, iz) + offset,
box,
maxDist,
norm,
distance
) > RayRelation::None) {
return start + (dir * glm::vec3(distance));
}
}
}
else {
} else {
return glm::vec3(px + t * dx, py + t * dy, pz + t * dz);
}
}
@@ -588,20 +618,17 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
ix += stepx;
t = txMax;
txMax += txDelta;
}
else {
} else {
iz += stepz;
t = tzMax;
tzMax += tzDelta;
}
}
else {
} else {
if (tyMax < tzMax) {
iy += stepy;
t = tyMax;
tyMax += tyDelta;
}
else {
} else {
iz += stepz;
t = tzMax;
tzMax += tzDelta;
@@ -611,19 +638,18 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis
return glm::vec3(px + maxDist * dx, py + maxDist * dy, pz + maxDist * dz);
}
void Chunks::setCenter(int32_t x, int32_t z) {
int cx = floordiv(x, CHUNK_W);
int cz = floordiv(z, CHUNK_D);
cx -= ox + w / 2;
cz -= oz + d / 2;
if (cx | cz) {
translate(cx,cz);
translate(cx, cz);
}
}
void Chunks::translate(int32_t dx, int32_t dz) {
for (uint i = 0; i < volume; i++){
for (uint i = 0; i < volume; i++) {
chunksSecond[i] = nullptr;
}
for (uint32_t z = 0; z < d; z++) {
@@ -631,9 +657,9 @@ void Chunks::translate(int32_t dx, int32_t dz) {
auto chunk = chunks[z * w + x];
int nx = x - dx;
int nz = z - dz;
if (chunk == nullptr)
continue;
if (nx < 0 || nz < 0 || nx >= static_cast<int>(w) || nz >= static_cast<int>(d)) {
if (chunk == nullptr) continue;
if (nx < 0 || nz < 0 || nx >= static_cast<int>(w) ||
nz >= static_cast<int>(d)) {
level->events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
save(chunk.get());
chunksCount--;
@@ -664,8 +690,10 @@ void Chunks::resize(uint32_t newW, uint32_t newD) {
const int newVolume = newW * newD;
std::vector<std::shared_ptr<Chunk>> newChunks(newVolume);
std::vector<std::shared_ptr<Chunk>> newChunksSecond(newVolume);
for (int z = 0; z < static_cast<int>(d) && z < static_cast<int>(newD); z++) {
for (int x = 0; x < static_cast<int>(w) && x < static_cast<int>(newW); x++) {
for (int z = 0; z < static_cast<int>(d) && z < static_cast<int>(newD);
z++) {
for (int x = 0; x < static_cast<int>(w) && x < static_cast<int>(newW);
x++) {
newChunks[z * newW + x] = chunks[z * w + x];
}
}
@@ -686,7 +714,8 @@ bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
int z = chunk->z;
x -= ox;
z -= oz;
if (x < 0 || z < 0 || x >= static_cast<int>(w) || z >= static_cast<int>(d)) {
if (x < 0 || z < 0 || x >= static_cast<int>(w) ||
z >= static_cast<int>(d)) {
return false;
}
chunks[z * w + x] = chunk;
@@ -695,7 +724,7 @@ bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
}
void Chunks::saveAndClear() {
for (size_t i = 0; i < volume; i++){
for (size_t i = 0; i < volume; i++) {
auto chunk = chunks[i].get();
chunks[i] = nullptr;
save(chunk);
@@ -705,9 +734,11 @@ void Chunks::saveAndClear() {
void Chunks::save(Chunk* chunk) {
if (chunk != nullptr) {
AABB aabb (
AABB aabb(
glm::vec3(chunk->x * CHUNK_W, -INFINITY, chunk->z * CHUNK_D),
glm::vec3((chunk->x+1) * CHUNK_W, INFINITY, (chunk->z + 1) * CHUNK_D)
glm::vec3(
(chunk->x + 1) * CHUNK_W, INFINITY, (chunk->z + 1) * CHUNK_D
)
);
auto entities = level->entities->getAllInside(aabb);
auto root = dynamic::create_map();
+31 -15
View File
@@ -2,12 +2,13 @@
#define VOXELS_CHUNKS_HPP_
#include <stdlib.h>
#include <vector>
#include <memory>
#include <glm/glm.hpp>
#include "voxel.hpp"
#include <glm/glm.hpp>
#include <memory>
#include <vector>
#include "../typedefs.hpp"
#include "voxel.hpp"
class VoxelRenderer;
@@ -26,8 +27,12 @@ class Chunks {
const ContentIndices* const indices;
void eraseSegments(const Block* def, blockstate state, int x, int y, int z);
void repairSegments(const Block* def, blockstate state, int x, int y, int z);
void setRotationExtended(Block* def, blockstate state, glm::ivec3 origin, uint8_t rotation);
void repairSegments(
const Block* def, blockstate state, int x, int y, int z
);
void setRotationExtended(
Block* def, blockstate state, glm::ivec3 origin, uint8_t rotation
);
public:
std::vector<std::shared_ptr<Chunk>> chunks;
std::vector<std::shared_ptr<Chunk>> chunksSecond;
@@ -38,8 +43,14 @@ public:
int32_t ox, oz;
WorldFiles* worldFiles;
Chunks(uint32_t w, uint32_t d, int32_t ox, int32_t oz,
WorldFiles* worldFiles, Level* level);
Chunks(
uint32_t w,
uint32_t d,
int32_t ox,
int32_t oz,
WorldFiles* worldFiles,
Level* level
);
~Chunks() = default;
bool putChunk(const std::shared_ptr<Chunk>& chunk);
@@ -68,16 +79,21 @@ public:
/// @param state the block state
/// @param coord position of the zone start
/// @param ignore ignored block id (will be counted as replaceable)
bool checkReplaceability(const Block* def, blockstate state, glm::ivec3 coord, blockid_t ignore=0);
bool checkReplaceability(
const Block* def,
blockstate state,
glm::ivec3 coord,
blockid_t ignore = 0
);
void setRotation(int32_t x, int32_t y, int32_t z, uint8_t rotation);
voxel* rayCast(
glm::vec3 start,
glm::vec3 dir,
float maxLength,
glm::vec3& end,
glm::ivec3& norm,
glm::vec3 start,
glm::vec3 dir,
float maxLength,
glm::vec3& end,
glm::ivec3& norm,
glm::ivec3& iend
);
@@ -100,4 +116,4 @@ public:
void saveAll();
};
#endif // VOXELS_CHUNKS_HPP_
#endif // VOXELS_CHUNKS_HPP_
+112 -103
View File
@@ -1,18 +1,18 @@
#include "ChunksStorage.hpp"
#include "VoxelsVolume.hpp"
#include "Chunk.hpp"
#include "Block.hpp"
#include "../content/Content.hpp"
#include "../debug/Logger.hpp"
#include "../files/WorldFiles.hpp"
#include "../items/Inventories.hpp"
#include "../lighting/Lightmap.hpp"
#include "../maths/voxmaths.hpp"
#include "../objects/Entities.hpp"
#include "../typedefs.hpp"
#include "../world/Level.hpp"
#include "../world/World.hpp"
#include "../maths/voxmaths.hpp"
#include "../lighting/Lightmap.hpp"
#include "../items/Inventories.hpp"
#include "../typedefs.hpp"
#include "../debug/Logger.hpp"
#include "Block.hpp"
#include "Chunk.hpp"
#include "VoxelsVolume.hpp"
static debug::Logger logger("chunks-storage");
@@ -20,22 +20,22 @@ ChunksStorage::ChunksStorage(Level* level) : level(level) {
}
void ChunksStorage::store(const std::shared_ptr<Chunk>& chunk) {
chunksMap[glm::ivec2(chunk->x, chunk->z)] = chunk;
chunksMap[glm::ivec2(chunk->x, chunk->z)] = chunk;
}
std::shared_ptr<Chunk> ChunksStorage::get(int x, int z) const {
auto found = chunksMap.find(glm::ivec2(x, z));
if (found == chunksMap.end()) {
return nullptr;
}
return found->second;
auto found = chunksMap.find(glm::ivec2(x, z));
if (found == chunksMap.end()) {
return nullptr;
}
return found->second;
}
void ChunksStorage::remove(int x, int z) {
auto found = chunksMap.find(glm::ivec2(x, z));
if (found != chunksMap.end()) {
chunksMap.erase(found->first);
}
auto found = chunksMap.find(glm::ivec2(x, z));
if (found != chunksMap.end()) {
chunksMap.erase(found->first);
}
}
static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) {
@@ -52,17 +52,17 @@ static void verifyLoadedChunk(ContentIndices* indices, Chunk* chunk) {
}
std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
World* world = level->getWorld();
World* world = level->getWorld();
auto& regions = world->wfile.get()->getRegions();
auto chunk = std::make_shared<Chunk>(x, z);
store(chunk);
auto data = regions.getChunk(chunk->x, chunk->z);
if (data) {
chunk->decode(data.get());
store(chunk);
auto data = regions.getChunk(chunk->x, chunk->z);
if (data) {
chunk->decode(data.get());
auto invs = regions.fetchInventories(chunk->x, chunk->z);
chunk->setBlockInventories(std::move(invs));
auto invs = regions.fetchInventories(chunk->x, chunk->z);
chunk->setBlockInventories(std::move(invs));
if (auto map = regions.fetchEntities(chunk->x, chunk->z)) {
level->entities->loadEntities(std::move(map));
@@ -70,95 +70,104 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
}
chunk->flags.loaded = true;
for(auto& entry : chunk->inventories) {
level->inventories->store(entry.second);
}
for (auto& entry : chunk->inventories) {
level->inventories->store(entry.second);
}
verifyLoadedChunk(level->content->getIndices(), chunk.get());
}
}
auto lights = regions.getLights(chunk->x, chunk->z);
if (lights) {
chunk->lightmap.set(lights.get());
auto lights = regions.getLights(chunk->x, chunk->z);
if (lights) {
chunk->lightmap.set(lights.get());
chunk->flags.loadedLights = true;
}
return chunk;
}
return chunk;
}
// reduce nesting on next modification
// 25.06.2024: not now
void ChunksStorage::getVoxels(VoxelsVolume* volume, bool backlight) const {
const Content* content = level->content;
auto indices = content->getIndices();
voxel* voxels = volume->getVoxels();
light_t* lights = volume->getLights();
int x = volume->getX();
int y = volume->getY();
int z = volume->getZ();
const Content* content = level->content;
auto indices = content->getIndices();
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 w = volume->getW();
int h = volume->getH();
int d = volume->getD();
int scx = floordiv(x, CHUNK_W);
int scz = floordiv(z, CHUNK_D);
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 ecx = floordiv(x + w, CHUNK_W);
int ecz = floordiv(z + d, CHUNK_D);
int cw = ecx - scx + 1;
int ch = ecz - scz + 1;
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++) {
const auto& found = chunksMap.find(glm::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++) {
uint idx = vox_index(lx - x, ly - y, lz - z, w, d);
voxels[idx].id = BLOCK_VOID;
lights[idx] = 0;
}
}
}
} else {
auto& 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++) {
uint vidx = vox_index(lx - x, ly - y, lz - z, w, d);
uint cidx = vox_index(lx - cx * CHUNK_W, ly,
lz - cz * CHUNK_D, CHUNK_W, CHUNK_D);
voxels[vidx] = cvoxels[cidx];
light_t light = clights[cidx];
if (backlight) {
auto block = indices->blocks.get(voxels[vidx].id);
if (block->lightPassing) {
light = Lightmap::combine(
min(15, Lightmap::extract(light, 0)+1),
min(15, Lightmap::extract(light, 1)+1),
min(15, Lightmap::extract(light, 2)+1),
min(15, Lightmap::extract(light, 3))
);
}
}
lights[vidx] = light;
}
}
}
}
}
}
// cw*ch chunks will be scanned
for (int cz = scz; cz < scz + ch; cz++) {
for (int cx = scx; cx < scx + cw; cx++) {
const auto& found = chunksMap.find(glm::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++) {
uint idx = vox_index(lx - x, ly - y, lz - z, w, d);
voxels[idx].id = BLOCK_VOID;
lights[idx] = 0;
}
}
}
} else {
auto& 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++) {
uint vidx = vox_index(lx - x, ly - y, lz - z, w, d);
uint cidx = vox_index(
lx - cx * CHUNK_W,
ly,
lz - cz * CHUNK_D,
CHUNK_W,
CHUNK_D
);
voxels[vidx] = cvoxels[cidx];
light_t light = clights[cidx];
if (backlight) {
auto block =
indices->blocks.get(voxels[vidx].id);
if (block->lightPassing) {
light = Lightmap::combine(
min(15,
Lightmap::extract(light, 0) + 1),
min(15,
Lightmap::extract(light, 1) + 1),
min(15,
Lightmap::extract(light, 2) + 1),
min(15, Lightmap::extract(light, 3))
);
}
}
lights[vidx] = light;
}
}
}
}
}
}
}
+4 -4
View File
@@ -3,8 +3,9 @@
#include <memory>
#include <unordered_map>
#include "voxel.hpp"
#include "../typedefs.hpp"
#include "voxel.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp"
@@ -23,9 +24,8 @@ public:
std::shared_ptr<Chunk> get(int x, int z) const;
void store(const std::shared_ptr<Chunk>& chunk);
void remove(int x, int y);
void getVoxels(VoxelsVolume* volume, bool backlight=false) const;
void getVoxels(VoxelsVolume* volume, bool backlight = false) const;
std::shared_ptr<Chunk> create(int x, int z);
};
#endif // VOXELS_CHUNKSSTORAGE_HPP_
#endif // VOXELS_CHUNKSSTORAGE_HPP_
+122 -89
View File
@@ -1,34 +1,30 @@
#include "DefaultWorldGenerator.hpp"
#include "voxel.hpp"
#include "Chunk.hpp"
#include "Block.hpp"
#include "Chunk.hpp"
#include "voxel.hpp"
#define FNL_IMPL
#include "../maths/FastNoiseLite.h"
#include "../content/Content.hpp"
#include "../maths/voxmaths.hpp"
#include "../maths/util.hpp"
#include "../core_defs.hpp"
#include <iostream>
#include <vector>
#include <time.h>
#include <stdexcept>
#include <math.h>
#include <time.h>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
#include <iostream>
#include <stdexcept>
#include <vector>
#include "../content/Content.hpp"
#include "../core_defs.hpp"
#include "../maths/FastNoiseLite.h"
#include "../maths/util.hpp"
#include "../maths/voxmaths.hpp"
// will be refactored in generators update
const int SEA_LEVEL = 55;
enum class MAPS{
SAND,
TREE,
CLIFF,
HEIGHT
};
enum class MAPS { SAND, TREE, CLIFF, HEIGHT };
#define MAPS_LEN 4
class Map2D {
@@ -37,12 +33,10 @@ class Map2D {
float* heights[MAPS_LEN];
public:
Map2D(int x, int z, int w, int d) : x(x), z(z), w(w), d(d) {
for (int i = 0; i < MAPS_LEN; i++)
heights[i] = new float[w*d];
for (int i = 0; i < MAPS_LEN; i++) heights[i] = new float[w * d];
}
~Map2D() {
for (int i = 0; i < MAPS_LEN; i++)
delete[] heights[i];
for (int i = 0; i < MAPS_LEN; i++) delete[] heights[i];
}
inline float get(MAPS map, int x, int z) {
@@ -64,63 +58,85 @@ public:
}
};
float calc_height(fnl_state *noise, int cur_x, int cur_z){
float calc_height(fnl_state* noise, int cur_x, int cur_z) {
float height = 0;
height += fnlGetNoise2D(noise, cur_x*0.0125f*8-125567,cur_z*0.0125f*8+3546);
height += fnlGetNoise2D(noise, cur_x*0.025f*8+4647,cur_z*0.025f*8-3436)*0.5f;
height += fnlGetNoise2D(noise, cur_x*0.05f*8-834176,cur_z*0.05f*8+23678)*0.25f;
height += fnlGetNoise2D(noise,
cur_x*0.2f*8 + fnlGetNoise2D(noise, cur_x*0.1f*8-23557,cur_z*0.1f*8-6568)*50,
cur_z*0.2f*8 + fnlGetNoise2D(noise, cur_x*0.1f*8+4363,cur_z*0.1f*8+4456)*50
) * fnlGetNoise2D(noise, cur_x*0.01f-834176,cur_z*0.01f+23678) * 0.25;
height += fnlGetNoise2D(noise, cur_x*0.1f*8-3465,cur_z*0.1f*8+4534)*0.125f;
height *= fnlGetNoise2D(noise, cur_x*0.1f+1000,cur_z*0.1f+1000)*0.5f+0.5f;
height += fnlGetNoise2D(
noise, cur_x * 0.0125f * 8 - 125567, cur_z * 0.0125f * 8 + 3546
);
height += fnlGetNoise2D(
noise, cur_x * 0.025f * 8 + 4647, cur_z * 0.025f * 8 - 3436
) *
0.5f;
height += fnlGetNoise2D(
noise, cur_x * 0.05f * 8 - 834176, cur_z * 0.05f * 8 + 23678
) *
0.25f;
height +=
fnlGetNoise2D(
noise,
cur_x * 0.2f * 8 +
fnlGetNoise2D(
noise, cur_x * 0.1f * 8 - 23557, cur_z * 0.1f * 8 - 6568
) * 50,
cur_z * 0.2f * 8 +
fnlGetNoise2D(
noise, cur_x * 0.1f * 8 + 4363, cur_z * 0.1f * 8 + 4456
) * 50
) *
fnlGetNoise2D(noise, cur_x * 0.01f - 834176, cur_z * 0.01f + 23678) *
0.25;
height +=
fnlGetNoise2D(noise, cur_x * 0.1f * 8 - 3465, cur_z * 0.1f * 8 + 4534) *
0.125f;
height *=
fnlGetNoise2D(noise, cur_x * 0.1f + 1000, cur_z * 0.1f + 1000) * 0.5f +
0.5f;
height += 1.0f;
height *= 64.0f;
return height;
}
int generate_tree(fnl_state *noise,
PseudoRandom* random,
Map2D& heights,
// Map2D& humidity,
int cur_x,
int cur_y,
int cur_z,
int tileSize,
blockid_t idWood,
blockid_t idLeaves){
int generate_tree(
fnl_state* noise,
PseudoRandom* random,
Map2D& heights,
// Map2D& humidity,
int cur_x,
int cur_y,
int cur_z,
int tileSize,
blockid_t idWood,
blockid_t idLeaves
) {
const int tileX = floordiv(cur_x, tileSize);
const int tileZ = floordiv(cur_z, tileSize);
random->setSeed(tileX*4325261+tileZ*12160951+tileSize*9431111);
random->setSeed(tileX * 4325261 + tileZ * 12160951 + tileSize * 9431111);
int randomX = (random->rand() % (tileSize/2)) - tileSize/4;
int randomZ = (random->rand() % (tileSize/2)) - tileSize/4;
int randomX = (random->rand() % (tileSize / 2)) - tileSize / 4;
int randomZ = (random->rand() % (tileSize / 2)) - tileSize / 4;
int centerX = tileX * tileSize + tileSize/2 + randomX;
int centerZ = tileZ * tileSize + tileSize/2 + randomZ;
int centerX = tileX * tileSize + tileSize / 2 + randomX;
int centerZ = tileZ * tileSize + tileSize / 2 + randomZ;
bool gentree = (random->rand() % 10) < heights.get(MAPS::TREE, centerX, centerZ) * 13;
if (!gentree)
return 0;
bool gentree =
(random->rand() % 10) < heights.get(MAPS::TREE, centerX, centerZ) * 13;
if (!gentree) return 0;
int height = (int)(heights.get(MAPS::HEIGHT, centerX, centerZ));
if (height < SEA_LEVEL+1)
return 0;
if (height < SEA_LEVEL + 1) return 0;
int lx = cur_x - centerX;
int radius = random->rand() % 4 + 2;
int ly = cur_y - height - 3 * radius;
int lz = cur_z - centerZ;
if (lx == 0 && lz == 0 && cur_y - height < (3*radius + radius/2))
if (lx == 0 && lz == 0 && cur_y - height < (3 * radius + radius / 2))
return idWood;
if (lx*lx+ly*ly/2+lz*lz < radius*radius)
return idLeaves;
if (lx * lx + ly * ly / 2 + lz * lz < radius * radius) return idLeaves;
return 0;
}
void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) {
const int treesTile = 12;
fnl_state noise = fnlCreateState();
noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
@@ -129,24 +145,27 @@ void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
PseudoRandom randomgrass;
int padding = 8;
Map2D heights(cx * CHUNK_W - padding,
cz * CHUNK_D - padding,
CHUNK_W + padding * 2,
CHUNK_D + padding * 2);
Map2D heights(
cx * CHUNK_W - padding,
cz * CHUNK_D - padding,
CHUNK_W + padding * 2,
CHUNK_D + padding * 2
);
for (int z = -padding; z < CHUNK_D+padding; z++){
for (int x = -padding; x < CHUNK_W+padding; x++){
for (int z = -padding; z < CHUNK_D + padding; z++) {
for (int x = -padding; x < CHUNK_W + padding; x++) {
int cur_x = x + cx * CHUNK_W;
int cur_z = z + cz * CHUNK_D;
float height = calc_height(&noise, cur_x, cur_z);
float hum = fnlGetNoise2D(&noise, cur_x * 0.3 + 633, cur_z * 0.3);
float sand = fnlGetNoise2D(&noise, cur_x * 0.1 - 633, cur_z * 0.1 + 1000);
float cliff = pow((sand + abs(sand)) / 2, 2);
float w = pow(fmax(-abs(height-SEA_LEVEL)+4,0)/6,2) * cliff;
float h1 = -abs(height-SEA_LEVEL - 0.03);
float h2 = abs(height-SEA_LEVEL + 0.04);
float h = (h1 + h2)*100;
height += (h * w);
float sand =
fnlGetNoise2D(&noise, cur_x * 0.1 - 633, cur_z * 0.1 + 1000);
float cliff = pow((sand + abs(sand)) / 2, 2);
float w = pow(fmax(-abs(height - SEA_LEVEL) + 4, 0) / 6, 2) * cliff;
float h1 = -abs(height - SEA_LEVEL - 0.03);
float h2 = abs(height - SEA_LEVEL + 0.04);
float h = (h1 + h2) * 100;
height += (h * w);
heights.set(MAPS::HEIGHT, cur_x, cur_z, height);
heights.set(MAPS::TREE, cur_x, cur_z, hum);
heights.set(MAPS::SAND, cur_x, cur_z, sand);
@@ -154,49 +173,63 @@ void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
}
}
for (int z = 0; z < CHUNK_D; z++){
for (int z = 0; z < CHUNK_D; z++) {
int cur_z = z + cz * CHUNK_D;
for (int x = 0; x < CHUNK_W; x++){
for (int x = 0; x < CHUNK_W; x++) {
int cur_x = x + cx * CHUNK_W;
float height = heights.get(MAPS::HEIGHT, cur_x, cur_z);
for (int cur_y = 0; cur_y < CHUNK_H; cur_y++){
for (int cur_y = 0; cur_y < CHUNK_H; cur_y++) {
// int cur_y = y;
int id = cur_y < SEA_LEVEL ? idWater : BLOCK_AIR;
blockstate state {};
if ((cur_y == (int)height) && (SEA_LEVEL-2 < cur_y)) {
if ((cur_y == (int)height) && (SEA_LEVEL - 2 < cur_y)) {
id = idGrassBlock;
} else if (cur_y < (height - 6)){
} else if (cur_y < (height - 6)) {
id = idStone;
} else if (cur_y < height){
} else if (cur_y < height) {
id = idDirt;
} else {
int tree = generate_tree(
&noise, &randomtree, heights,
cur_x, cur_y, cur_z,
treesTile, idWood, idLeaves);
&noise,
&randomtree,
heights,
cur_x,
cur_y,
cur_z,
treesTile,
idWood,
idLeaves
);
if (tree) {
id = tree;
state.rotation = BLOCK_DIR_UP;
}
}
float sand = fmax(heights.get(MAPS::SAND, cur_x, cur_z), heights.get(MAPS::CLIFF, cur_x, cur_z));
if (((height - (1.1 - 0.2 * pow(height - 54, 4)) +
(5*sand)) < cur_y + (height - 0.01- (int)height))
&& (cur_y < height)){
float sand = fmax(
heights.get(MAPS::SAND, cur_x, cur_z),
heights.get(MAPS::CLIFF, cur_x, cur_z)
);
if (((height - (1.1 - 0.2 * pow(height - 54, 4)) + (5 * sand)) <
cur_y + (height - 0.01 - (int)height)) &&
(cur_y < height)) {
id = idSand;
}
if (cur_y <= 2)
id = idBazalt;
if (cur_y <= 2) id = idBazalt;
randomgrass.setSeed(cur_x,cur_z);
if ((id == 0) && ((height > SEA_LEVEL+0.4) || (sand > 0.1)) && ((int)(height + 1) == cur_y) && ((unsigned short)randomgrass.rand() > 56000)){
randomgrass.setSeed(cur_x, cur_z);
if ((id == 0) && ((height > SEA_LEVEL + 0.4) || (sand > 0.1)) &&
((int)(height + 1) == cur_y) &&
((unsigned short)randomgrass.rand() > 56000)) {
id = idGrass;
}
if ((id == 0) && (height > SEA_LEVEL+0.4) && ((int)(height + 1) == cur_y) && ((unsigned short)randomgrass.rand() > 65000)){
if ((id == 0) && (height > SEA_LEVEL + 0.4) &&
((int)(height + 1) == cur_y) &&
((unsigned short)randomgrass.rand() > 65000)) {
id = idFlower;
}
if ((height > SEA_LEVEL+1) && ((int)(height + 1) == cur_y) && ((unsigned short)randomgrass.rand() > 65533)){
if ((height > SEA_LEVEL + 1) && ((int)(height + 1) == cur_y) &&
((unsigned short)randomgrass.rand() > 65533)) {
id = idWood;
state.rotation = BLOCK_DIR_UP;
}
+3 -3
View File
@@ -9,10 +9,10 @@ class Content;
class DefaultWorldGenerator : WorldGenerator {
public:
DefaultWorldGenerator(const Content* content) : WorldGenerator(content) {}
DefaultWorldGenerator(const Content* content) : WorldGenerator(content) {
}
void generate(voxel* voxels, int x, int z, int seed);
};
#endif // VOXELS_DEFAULTWORLDGENERATOR_HPP_
#endif // VOXELS_DEFAULTWORLDGENERATOR_HPP_
+7 -7
View File
@@ -1,24 +1,24 @@
#include "FlatWorldGenerator.hpp"
#include "voxel.hpp"
#include "Chunk.hpp"
#include "../content/Content.hpp"
#include "../core_defs.hpp"
#include "Chunk.hpp"
#include "voxel.hpp"
void FlatWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) {
for (int z = 0; z < CHUNK_D; z++) {
for (int x = 0; x < CHUNK_W; x++) {
for (int cur_y = 0; cur_y < CHUNK_H; cur_y++){
for (int cur_y = 0; cur_y < CHUNK_H; cur_y++) {
int id = BLOCK_AIR;
blockstate state {};
if(cur_y == 2) {
if (cur_y == 2) {
id = idBazalt;
} else if(cur_y == 6) {
} else if (cur_y == 6) {
id = idGrassBlock;
} else if(cur_y > 2 && cur_y <= 5) {
} else if (cur_y > 2 && cur_y <= 5) {
id = idDirt;
}
}
voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].id = id;
voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].state = state;
+3 -3
View File
@@ -9,10 +9,10 @@ class Content;
class FlatWorldGenerator : WorldGenerator {
public:
FlatWorldGenerator(const Content* content) : WorldGenerator(content) {}
FlatWorldGenerator(const Content* content) : WorldGenerator(content) {
}
void generate(voxel* voxels, int x, int z, int seed);
};
#endif // VOXELS_FLATWORLDGENERATOR_HPP_
#endif // VOXELS_FLATWORLDGENERATOR_HPP_
+14 -9
View File
@@ -1,20 +1,25 @@
#include "VoxelsVolume.hpp"
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(std::make_unique<voxel[]>(w * h * d)),
lights(std::make_unique<light_t[]>(w * h * d))
{
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(std::make_unique<voxel[]>(w * h * d)),
lights(std::make_unique<light_t[]>(w * h * d)) {
for (int i = 0; i < w * h * d; i++) {
voxels[i].id = BLOCK_VOID;
}
}
VoxelsVolume::VoxelsVolume(int w, int h, int d) : VoxelsVolume(0, 0, 0, w, h, d)
{}
VoxelsVolume::VoxelsVolume(int w, int h, int d)
: VoxelsVolume(0, 0, 0, w, h, d) {
}
VoxelsVolume::~VoxelsVolume() {}
VoxelsVolume::~VoxelsVolume() {
}
void VoxelsVolume::setPosition(int x, int y, int z) {
this->x = x;
+6 -4
View File
@@ -1,8 +1,8 @@
#ifndef VOXELS_VOXELSVOLUME_HPP_
#define VOXELS_VOXELSVOLUME_HPP_
#include "../typedefs.hpp"
#include "../constants.hpp"
#include "../typedefs.hpp"
#include "voxel.hpp"
class VoxelsVolume {
@@ -50,18 +50,20 @@ public:
}
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) {
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) {
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_HPP_
#endif // VOXELS_VOXELSVOLUME_HPP_
+14 -13
View File
@@ -1,18 +1,19 @@
#include "WorldGenerator.hpp"
#include "voxel.hpp"
#include "Chunk.hpp"
#include "Block.hpp"
#include "../content/Content.hpp"
#include "Block.hpp"
#include "Chunk.hpp"
#include "voxel.hpp"
WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->blocks.require("base:stone").rt.id),
idDirt(content->blocks.require("base:dirt").rt.id),
idGrassBlock(content->blocks.require("base:grass_block").rt.id),
idSand(content->blocks.require("base:sand").rt.id),
idWater(content->blocks.require("base:water").rt.id),
idWood(content->blocks.require("base:wood").rt.id),
idLeaves(content->blocks.require("base:leaves").rt.id),
idGrass(content->blocks.require("base:grass").rt.id),
idFlower(content->blocks.require("base:flower").rt.id),
idBazalt(content->blocks.require("base:bazalt").rt.id) {}
: idStone(content->blocks.require("base:stone").rt.id),
idDirt(content->blocks.require("base:dirt").rt.id),
idGrassBlock(content->blocks.require("base:grass_block").rt.id),
idSand(content->blocks.require("base:sand").rt.id),
idWater(content->blocks.require("base:water").rt.id),
idWood(content->blocks.require("base:wood").rt.id),
idLeaves(content->blocks.require("base:leaves").rt.id),
idGrass(content->blocks.require("base:grass").rt.id),
idFlower(content->blocks.require("base:flower").rt.id),
idBazalt(content->blocks.require("base:bazalt").rt.id) {
}
+3 -2
View File
@@ -1,9 +1,10 @@
#ifndef VOXELS_WORLDGENERATOR_HPP_
#define VOXELS_WORLDGENERATOR_HPP_
#include "../typedefs.hpp"
#include <string>
#include "../typedefs.hpp"
struct voxel;
class Content;
@@ -26,4 +27,4 @@ public:
virtual void generate(voxel* voxels, int x, int z, int seed) = 0;
};
#endif // VOXELS_WORLDGENERATOR_HPP_
#endif // VOXELS_WORLDGENERATOR_HPP_
+9 -10
View File
@@ -11,14 +11,14 @@ inline constexpr int BLOCK_DIR_UP = 0x4;
inline constexpr int BLOCK_DIR_DOWN = 0x5;
struct blockstate {
uint8_t rotation : 3; // block rotation index
uint8_t segment : 3; // segment block bits
uint8_t reserved : 2; // reserved bits
uint8_t userbits : 8; // bits for use in block script
uint8_t rotation : 3; // block rotation index
uint8_t segment : 3; // segment block bits
uint8_t reserved : 2; // reserved bits
uint8_t userbits : 8; // bits for use in block script
};
static_assert (sizeof(blockstate) == 2);
static_assert(sizeof(blockstate) == 2);
/// @brief blockstate cast to an integer (optimized out in most cases)
/// @brief blockstate cast to an integer (optimized out in most cases)
inline constexpr blockstate_t blockstate2int(blockstate b) {
return static_cast<blockstate_t>(b.rotation) |
static_cast<blockstate_t>(b.segment) << 3 |
@@ -26,14 +26,13 @@ inline constexpr blockstate_t blockstate2int(blockstate b) {
static_cast<blockstate_t>(b.userbits) << 8;
}
/// @brief integer cast to a blockstate (optimized out in most cases)
/// @brief integer cast to a blockstate (optimized out in most cases)
inline constexpr blockstate int2blockstate(blockstate_t i) {
return {
static_cast<uint8_t>(i & 0b111),
static_cast<uint8_t>((i >> 3) & 0b111),
static_cast<uint8_t>((i >> 6) & 0b11),
static_cast<uint8_t>((i >> 8) & 0xFF)
};
static_cast<uint8_t>((i >> 8) & 0xFF)};
}
struct voxel {
@@ -42,4 +41,4 @@ struct voxel {
};
static_assert(sizeof(voxel) == 4);
#endif // VOXELS_VOXEL_HPP_
#endif // VOXELS_VOXEL_HPP_