Zstd dictionary, forward decl
This commit is contained in:
parent
8d967cee06
commit
752cd4b1a3
|
@ -36,7 +36,7 @@ add_definitions(
|
|||
-mfma
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
file(GLOB_RECURSE SOURCES "src/*/*.cpp")
|
||||
file(GLOB INCLUDE_SOURCES "include/imgui-1.76/*.cpp" "include/FastNoiseSIMD/*.cpp" "include/Remotery/lib/*.c")
|
||||
set(INCLUDE_LIBS
|
||||
"include/imgui-1.76"
|
||||
|
@ -46,7 +46,7 @@ set(INCLUDE_LIBS
|
|||
"include/robin_hood"
|
||||
)
|
||||
|
||||
add_executable(univerxel ${SOURCES} ${INCLUDE_SOURCES})
|
||||
add_executable(univerxel "src/main.cpp" ${SOURCES} ${INCLUDE_SOURCES})
|
||||
target_compile_features(univerxel PUBLIC cxx_std_17)
|
||||
target_link_libraries(univerxel ${LINKED_LIBS})
|
||||
target_include_directories(univerxel PRIVATE ${INCLUDE_LIBS})
|
||||
|
@ -55,6 +55,7 @@ if(PROFILING)
|
|||
else(PROFILING)
|
||||
target_compile_definitions(univerxel PRIVATE RMT_ENABLED=0)
|
||||
endif(PROFILING)
|
||||
add_dependencies(univerxel generate_dictionary)
|
||||
|
||||
file(COPY content/shaders DESTINATION ${CMAKE_BINARY_DIR}/content)
|
||||
file(COPY content/textures DESTINATION ${CMAKE_BINARY_DIR}/content)
|
||||
|
@ -64,4 +65,17 @@ add_custom_target(docs
|
|||
COMMAND doxygen ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Build doc."
|
||||
)
|
||||
)
|
||||
|
||||
# Zstd dictionary
|
||||
file(GLOB SMP_SOURCES "src/chunk_sampler.cpp" "src/world/Chunk.cpp" "include/FastNoiseSIMD/*.cpp")
|
||||
add_executable(chunk_sampler EXCLUDE_FROM_ALL ${SMP_SOURCES})
|
||||
target_compile_features(chunk_sampler PUBLIC cxx_std_17)
|
||||
target_link_libraries(chunk_sampler ${LINKED_LIBS})
|
||||
target_include_directories(chunk_sampler PRIVATE "include/FastNoiseSIMD")
|
||||
|
||||
add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/content/zstd.dict"
|
||||
COMMAND "${CMAKE_BINARY_DIR}/chunk_sampler"
|
||||
COMMAND zstd --train "${CMAKE_BINARY_DIR}/samples/*" -o "${CMAKE_BINARY_DIR}/content/zstd.dict"
|
||||
DEPENDS chunk_sampler)
|
||||
add_custom_target(generate_dictionary DEPENDS "${CMAKE_BINARY_DIR}/content/zstd.dict")
|
7
TODO.md
7
TODO.md
|
@ -11,7 +11,7 @@
|
|||
- [~] Group files
|
||||
- [x] Zstd + custom grouping
|
||||
- [~] Find best region size
|
||||
- [ ] Zstd Train dictionary
|
||||
- [x] Zstd Train dictionary
|
||||
- [~] Low memory: Keep only ifstream
|
||||
- [ ] Unload unused
|
||||
- [ ] In memory RLE
|
||||
|
@ -28,10 +28,15 @@
|
|||
- [ ] Leak test
|
||||
- Valgrind
|
||||
- Xtree-memory
|
||||
- [ ] sanitizer
|
||||
- [ ] clang-tidy
|
||||
- [ ] cmake
|
||||
- https://github.com/microsoft/GSL/blob/master/include/gsl/pointers
|
||||
- [ ] Server
|
||||
- [ ] ZeroMQ
|
||||
- [ ] Mutex guard
|
||||
- [ ] Shared mutex
|
||||
- [ ] Logger
|
||||
|
||||
## Rendering
|
||||
- [x] Render triangle
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* \file chunk_sampler.cpp
|
||||
* \brief Generate uncompressed chunks
|
||||
* \author Maelys Bois
|
||||
* \version 0.0.1
|
||||
*
|
||||
* Generate random uncompressed chunks for Zstd dictionary training.
|
||||
*/
|
||||
|
||||
#include "world/Chunk.hpp"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
|
||||
/// Entry point
|
||||
int main(int, char *[])
|
||||
{
|
||||
std::srand(std::time(nullptr));
|
||||
world::Generator generator(std::rand());
|
||||
std::filesystem::create_directories("samples");
|
||||
for (size_t i = 0; i < 10000; i++)
|
||||
{
|
||||
world::Chunk chunk(chunk_pos(std::rand(), std::rand(), std::rand()), generator);
|
||||
std::ofstream out("samples/" + std::to_string(i));
|
||||
chunk.write(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,16 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "../data/glm.hpp"
|
||||
#include "../render/buffer/Abstract.hpp"
|
||||
#include "../data/geometry/Frustum.hpp"
|
||||
#include "../data/geometry/Faces.hpp"
|
||||
#include <memory>
|
||||
#include <toml.h>
|
||||
#include <robin_hood.h>
|
||||
#include "../world/forward.h"
|
||||
typedef glm::vec3 camera_pos;
|
||||
|
||||
namespace world {
|
||||
class Chunk;
|
||||
}
|
||||
/// Mesh creation
|
||||
namespace contouring {
|
||||
/// Generating mesh from world data
|
||||
|
@ -24,10 +19,10 @@ namespace contouring {
|
|||
virtual void update(const camera_pos &pos) = 0;
|
||||
|
||||
/// Chunk data change
|
||||
virtual void onUpdate(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>>& data, geometry::Faces neighbors) = 0;
|
||||
virtual void onUpdate(const chunk_pos &pos, const world::chunk_map& data, geometry::Faces neighbors) = 0;
|
||||
/// Chunk existante ping
|
||||
/// @note notify for chunks entering view while moving
|
||||
virtual void onNotify(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data) = 0;
|
||||
virtual void onNotify(const chunk_pos &pos, const world::chunk_map &data) = 0;
|
||||
/// Display ImGui config
|
||||
virtual void onGui() = 0;
|
||||
/// Get options
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "AbstractFlat.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <toml.h>
|
||||
#include "../world/Chunk.hpp"
|
||||
|
||||
namespace contouring {
|
||||
|
@ -42,7 +43,7 @@ namespace contouring {
|
|||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(scale));
|
||||
for (const auto [pos, buffer] : buffers) {
|
||||
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(scale * glm::vec3(pos) * glm::vec3(CHUNK_LENGTH), scale * glm::vec3(CHUNK_LENGTH)))))
|
||||
out.push_back({glm::translate(scaling, glm::vec3(pos) * glm::vec3(CHUNK_LENGTH)), buffer});
|
||||
out.emplace_back(glm::translate(scaling, glm::vec3(pos) * glm::vec3(CHUNK_LENGTH)), buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Abstract.hpp"
|
||||
#include "../data/math.hpp"
|
||||
|
||||
namespace contouring {
|
||||
/// Generating mesh for chunks 1:1
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace contouring {
|
|||
virtual ~Dummy() { }
|
||||
|
||||
void update(const camera_pos &) override { }
|
||||
void onUpdate(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &, geometry::Faces) override {}
|
||||
void onNotify(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &) override { }
|
||||
void onUpdate(const chunk_pos &, const world::chunk_map &, geometry::Faces) override {}
|
||||
void onNotify(const chunk_pos &, const world::chunk_map &) override { }
|
||||
void onGui() override { }
|
||||
std::string getOptions() override { return ""; }
|
||||
void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &, const std::optional<geometry::Frustum>&, float) override { }
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../world/materials.hpp"
|
||||
#include <Remotery.h>
|
||||
#include <imgui.h>
|
||||
#include <toml.h>
|
||||
#include "dualmc.h"
|
||||
|
||||
namespace contouring {
|
||||
|
@ -13,7 +14,7 @@ namespace contouring {
|
|||
manifold = opt["manifold"].value_or(manifold);
|
||||
|
||||
for (size_t i = 1; i <= 2; i++) {
|
||||
workers.push_back(std::thread([&] {
|
||||
workers.emplace_back([&] {
|
||||
while (running) {
|
||||
std::pair<chunk_pos, surrounding::corners> ctx;
|
||||
loadQueue.wait();
|
||||
|
@ -21,10 +22,10 @@ namespace contouring {
|
|||
rmt_ScopedCPUSample(ProcessContouring, 0);
|
||||
buffer::ShortIndexed::Data data;
|
||||
render(ctx.second, data);
|
||||
loadedQueue.push({ctx.first, data});
|
||||
loadedQueue.emplace(ctx.first, data);
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
FlatDualMC::~FlatDualMC() {
|
||||
|
@ -48,7 +49,7 @@ namespace contouring {
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
void FlatDualMC::enqueue(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data) {
|
||||
void FlatDualMC::enqueue(const chunk_pos &pos, const world::chunk_map &data) {
|
||||
rmt_ScopedCPUSample(EnqueueContouring, RMTSF_Aggregate);
|
||||
const auto dist2 = glm::length2(pos - center);
|
||||
if (dist2 <= loadDistance * loadDistance) {
|
||||
|
@ -59,7 +60,7 @@ namespace contouring {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatDualMC::onUpdate(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data, geometry::Faces neighbors) {
|
||||
void FlatDualMC::onUpdate(const chunk_pos &pos, const world::chunk_map &data, geometry::Faces neighbors) {
|
||||
enqueue(pos, data);
|
||||
if (neighbors && (geometry::Faces::Left | geometry::Faces::Down | geometry::Faces::Backward)) {
|
||||
for (size_t i = 1; i < 8; i++) {
|
||||
|
@ -68,7 +69,7 @@ namespace contouring {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatDualMC::onNotify(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data) {
|
||||
void FlatDualMC::onNotify(const chunk_pos &pos, const world::chunk_map &data) {
|
||||
if (buffers.find(pos) == buffers.end()) {
|
||||
enqueue(pos, data);
|
||||
}
|
||||
|
@ -109,15 +110,14 @@ namespace contouring {
|
|||
void FlatDualMC::render(const surrounding::corners &surrounding, buffer::ShortIndexed::Data &out) const {
|
||||
const int SIZE = CHUNK_LENGTH + 3;
|
||||
std::vector<dualmc::DualMC<float>::Point> grid;
|
||||
grid.reserve(SIZE * SIZE * SIZE);
|
||||
{
|
||||
grid.reserve(SIZE * SIZE * SIZE);
|
||||
for (int z = 0; z < SIZE; z++) {
|
||||
for (int y = 0; y < SIZE; y++) {
|
||||
for (int x = 0; x < SIZE; x++) {
|
||||
const auto chunk = surrounding[(z >= CHUNK_LENGTH) + (y >= CHUNK_LENGTH)*2 + (x >= CHUNK_LENGTH)*4];
|
||||
// MAYBE: area copy
|
||||
const auto voxel = chunk->getAt(chunk_voxel_pos(x % CHUNK_LENGTH, y % CHUNK_LENGTH, z % CHUNK_LENGTH));
|
||||
grid.push_back({voxel.Density * 1.f / UCHAR_MAX, voxel.Material});
|
||||
const auto &chunk = surrounding[(z >= CHUNK_LENGTH) + (y >= CHUNK_LENGTH)*2 + (x >= CHUNK_LENGTH)*4];
|
||||
const auto &voxel = chunk->getAt(chunk_voxel_pos(x % CHUNK_LENGTH, y % CHUNK_LENGTH, z % CHUNK_LENGTH));
|
||||
grid.emplace_back(voxel.Density * 1.f / UCHAR_MAX, voxel.Material);
|
||||
}}}
|
||||
}
|
||||
{
|
||||
|
@ -131,9 +131,9 @@ namespace contouring {
|
|||
out.materials.reserve(dmc_vertices.size());
|
||||
out.normals.reserve(dmc_vertices.size());
|
||||
for (const auto& v: dmc_vertices) {
|
||||
out.vertices.push_back(glm::vec3(v.x, v.y, v.z));
|
||||
out.materials.push_back(v.w);
|
||||
out.normals.push_back(glm::vec3(0));
|
||||
out.vertices.emplace_back(v.x, v.y, v.z);
|
||||
out.materials.emplace_back(v.w);
|
||||
out.normals.emplace_back(0);
|
||||
}
|
||||
|
||||
out.indices.reserve(dmc_tris.size());
|
||||
|
|
|
@ -26,10 +26,10 @@ namespace contouring {
|
|||
std::string getOptions() override;
|
||||
|
||||
/// Chunk data change
|
||||
void onUpdate(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &, geometry::Faces) override;
|
||||
void onUpdate(const chunk_pos &, const world::chunk_map &, geometry::Faces) override;
|
||||
/// Chunk existante ping
|
||||
/// @note notify for chunks entering view while moving
|
||||
void onNotify(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &) override;
|
||||
void onNotify(const chunk_pos &, const world::chunk_map &) override;
|
||||
|
||||
protected:
|
||||
safe_priority_queue_map<chunk_pos, surrounding::corners, int> loadQueue;
|
||||
|
@ -44,7 +44,7 @@ namespace contouring {
|
|||
bool running = true;
|
||||
std::vector<std::thread> workers;
|
||||
|
||||
void enqueue(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &);
|
||||
void enqueue(const chunk_pos &, const world::chunk_map &);
|
||||
|
||||
float iso = .1f;
|
||||
bool manifold = true;
|
||||
|
|
|
@ -9,7 +9,7 @@ using namespace geometry;
|
|||
namespace contouring {
|
||||
FlatSurroundingBox::FlatSurroundingBox(const std::string &opt) : AbstractFlat(opt) {
|
||||
for (size_t i = 1; i <= 4; i++) {
|
||||
workers.push_back(std::thread([&] {
|
||||
workers.emplace_back([&] {
|
||||
while (running) {
|
||||
std::pair<chunk_pos, surrounding::faces> ctx;
|
||||
loadQueue.wait();
|
||||
|
@ -19,11 +19,11 @@ namespace contouring {
|
|||
render(ctx.second, vertices);
|
||||
{
|
||||
rmt_ScopedCPUSample(Index, 0);
|
||||
loadedQueue.push({ctx.first, buffer::ShortIndexed::Data(vertices)});
|
||||
loadedQueue.emplace(ctx.first, vertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
FlatSurroundingBox::~FlatSurroundingBox() {
|
||||
|
@ -36,7 +36,7 @@ namespace contouring {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatSurroundingBox::enqueue(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data) {
|
||||
void FlatSurroundingBox::enqueue(const chunk_pos &pos, const world::chunk_map &data) {
|
||||
rmt_ScopedCPUSample(EnqueueContouring, RMTSF_Aggregate);
|
||||
const auto dist2 = glm::length2(pos - center);
|
||||
if (dist2 <= loadDistance * loadDistance) {
|
||||
|
@ -47,7 +47,7 @@ namespace contouring {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatSurroundingBox::onUpdate(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data, Faces neighbors) {
|
||||
void FlatSurroundingBox::onUpdate(const chunk_pos &pos, const world::chunk_map &data, Faces neighbors) {
|
||||
enqueue(pos, data);
|
||||
if (neighbors && Faces::Right)
|
||||
enqueue(pos + g_face_offsets[static_cast<int>(Face::Right)], data);
|
||||
|
@ -68,7 +68,7 @@ namespace contouring {
|
|||
enqueue(pos + g_face_offsets[static_cast<int>(Face::Backward)], data);
|
||||
}
|
||||
|
||||
void FlatSurroundingBox::onNotify(const chunk_pos &pos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &data) {
|
||||
void FlatSurroundingBox::onNotify(const chunk_pos &pos, const world::chunk_map &data) {
|
||||
if (buffers.find(pos) == buffers.end()) {
|
||||
enqueue(pos, data);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,10 @@ namespace contouring {
|
|||
void onGui() override;
|
||||
|
||||
/// Chunk data change
|
||||
void onUpdate(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &, geometry::Faces) override;
|
||||
void onUpdate(const chunk_pos &, const world::chunk_map &, geometry::Faces) override;
|
||||
/// Chunk existante ping
|
||||
/// @note notify for chunks entering view while moving
|
||||
void onNotify(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &) override;
|
||||
void onNotify(const chunk_pos &, const world::chunk_map &) override;
|
||||
|
||||
protected:
|
||||
safe_priority_queue_map<chunk_pos, surrounding::faces, int> loadQueue;
|
||||
|
@ -42,7 +42,7 @@ namespace contouring {
|
|||
bool running = true;
|
||||
std::vector<std::thread> workers;
|
||||
|
||||
void enqueue(const chunk_pos &, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &);
|
||||
void enqueue(const chunk_pos &, const world::chunk_map &);
|
||||
|
||||
private:
|
||||
static inline bool isTransparent(const surrounding::faces &surrounding, const std::pair<ushort, ushort> &idx);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace contouring::box {
|
|||
|
||||
static void addQuad(std::vector<buffer::VertexData> & out, glm::vec3 position, ushort material, Face face, glm::vec3 size) {
|
||||
for (auto vertex : g_quad_vertices) {
|
||||
out.push_back(buffer::VertexData{glm::vec3(g_cube_rotate[static_cast<int>(face)] * glm::vec4(vertex, 1)) * size + position, material, g_cube_normals[static_cast<int>(face)]});
|
||||
out.emplace_back(glm::vec3(g_cube_rotate[static_cast<int>(face)] * glm::vec4(vertex, 1)) * size + position, material, g_cube_normals[static_cast<int>(face)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Abstract.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace contouring {
|
||||
static const std::array<std::string, 3> names = {"FlatDualMC", "FlatBox", "Dummy"};
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "surrounding.hpp"
|
||||
|
||||
#include "../world/Chunk.hpp"
|
||||
#include "../data/math.hpp"
|
||||
|
||||
using namespace geometry;
|
||||
namespace contouring::surrounding {
|
||||
bool load(faces &out, const chunk_pos &chunkPos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &chunks) {
|
||||
bool load(faces &out, const chunk_pos &chunkPos, const world::chunk_map &chunks) {
|
||||
{
|
||||
const auto it = chunks.find(chunkPos);
|
||||
if (it == chunks.end())
|
||||
|
@ -59,7 +60,7 @@ namespace contouring::surrounding {
|
|||
}
|
||||
}
|
||||
|
||||
bool load(corners &out, const chunk_pos &chunkPos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &chunks) {
|
||||
bool load(corners &out, const chunk_pos &chunkPos, const world::chunk_map &chunks) {
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
const auto it = chunks.find(chunkPos + g_corner_offsets[i]);
|
||||
if (it == chunks.end())
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../data/geometry/Faces.hpp"
|
||||
#include <memory>
|
||||
#include <robin_hood.h>
|
||||
#include "../world/forward.h"
|
||||
|
||||
namespace world {
|
||||
class Chunk;
|
||||
|
@ -11,7 +10,7 @@ namespace contouring::surrounding {
|
|||
const auto CENTER = 6;
|
||||
typedef std::array<std::shared_ptr<const world::Chunk>, CENTER+1> faces;
|
||||
|
||||
bool load(faces &out, const chunk_pos &chunkPos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &chunks);
|
||||
bool load(faces &out, const chunk_pos &chunkPos, const world::chunk_map &chunks);
|
||||
|
||||
std::pair<ushort, ushort> getNeighborIdx(ushort idx, geometry::Face face);
|
||||
|
||||
|
@ -27,5 +26,5 @@ namespace contouring::surrounding {
|
|||
glm::ivec3(1, 1, 1),
|
||||
};
|
||||
|
||||
bool load(corners &out, const chunk_pos &chunkPos, const robin_hood::unordered_map<chunk_pos, std::shared_ptr<world::Chunk>> &chunks);
|
||||
bool load(corners &out, const chunk_pos &chunkPos, const world::chunk_map &chunks);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../data/glm.hpp"
|
||||
#include "../data/geometry/Frustum.hpp"
|
||||
#include "../data/geometry/Ray.hpp"
|
||||
typedef glm::vec3 camera_pos;
|
||||
|
||||
/// Moving perspective camera
|
||||
class Camera {
|
||||
|
@ -37,10 +38,10 @@ public:
|
|||
inline geometry::Frustum getFrustum() const { return geometry::Frustum(ViewMatrix, ProjectionMatrix); }
|
||||
inline geometry::Ray getRay() const { return geometry::Ray(Position, getDirection(), o.far); }
|
||||
|
||||
glm::mat4 getViewMatrix() const { return ViewMatrix; }
|
||||
glm::mat4 getProjectionMatrix() const { return ProjectionMatrix; }
|
||||
camera_pos getPosition() const { return Position; }
|
||||
float getDepth() const { return o.far; }
|
||||
constexpr glm::mat4 getViewMatrix() const { return ViewMatrix; }
|
||||
constexpr glm::mat4 getProjectionMatrix() const { return ProjectionMatrix; }
|
||||
constexpr camera_pos getPosition() const { return Position; }
|
||||
constexpr float getDepth() const { return o.far; }
|
||||
|
||||
private:
|
||||
GLFWwindow *window;
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace geometry {
|
|||
|
||||
/// Get path points in integer grid
|
||||
/// @note not precise enough
|
||||
inline void grid(std::vector<voxel_pos>& points) const {
|
||||
voxel_pos current = from + glm::vec3(.5f);
|
||||
voxel_pos d = dir * dist;
|
||||
voxel_pos inc = voxel_pos((d.x < 0) ? -1 : 1, (d.y < 0) ? -1 : 1, (d.z < 0) ? -1 : 1);
|
||||
voxel_pos size = glm::abs(d);
|
||||
voxel_pos delta = size << 1ll;
|
||||
inline void grid(std::vector<glm::lvec3>& points) const {
|
||||
glm::lvec3 current = from + glm::vec3(.5f);
|
||||
const glm::lvec3 d = dir * dist;
|
||||
const glm::lvec3 inc = glm::lvec3((d.x < 0) ? -1 : 1, (d.y < 0) ? -1 : 1, (d.z < 0) ? -1 : 1);
|
||||
const glm::lvec3 size = glm::abs(d);
|
||||
const glm::lvec3 delta = size << 1ll;
|
||||
|
||||
if ((size.x >= size.y) && (size.x >= size.z)) {
|
||||
int err_1 = delta.y - size.x;
|
||||
|
|
|
@ -20,7 +20,7 @@ struct SphereIterator {
|
|||
out.reserve(out.size() + dxz * dxz);
|
||||
for (int z = minz; z <= maxz; z++) {
|
||||
for (int x = minx; x <= maxx; x++) {
|
||||
out.push_back(glm::ivec3(x, y, z));
|
||||
out.emplace_back(x, y, z);
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/hash.hpp>
|
||||
|
||||
namespace glm {
|
||||
typedef vec<3, long long> lvec3;
|
||||
typedef vec<4, long long> lvec4;
|
||||
typedef vec<3, ushort> usvec3;
|
||||
typedef vec<3, unsigned char> ucvec3;
|
||||
} // namespace glm
|
||||
|
||||
typedef glm::vec3 camera_pos;
|
||||
typedef glm::lvec3 voxel_pos;
|
||||
typedef glm::ivec3 chunk_pos;
|
||||
typedef glm::ucvec3 chunk_voxel_pos;
|
||||
typedef glm::ivec3 region_pos;
|
||||
typedef glm::ucvec3 region_chunk_pos;
|
||||
|
||||
namespace glm {
|
||||
ivec3 inline iround(const vec3& p) {
|
||||
return ivec3(std::round<int>(p.x), std::round<int>(p.y), std::round<int>(p.z));
|
||||
}
|
||||
int inline length2(const ivec3& a) {
|
||||
return a.x * a.x + a.y * a.y + a.z * a.z;
|
||||
}
|
||||
ivec3 inline diff(const ivec3& a, const ivec3& b) {
|
||||
return glm::abs(glm::abs(a) - glm::abs(b));
|
||||
}
|
||||
|
||||
uint inline rem(long long value, uint m) {
|
||||
return value < 0 ? ((value+1) % (long long)m) + m - 1 : value % (long long)m;
|
||||
}
|
||||
int inline div(long long value, uint m) {
|
||||
return value < 0 ? ((value+1) / (long long)m) - 1 : value / (long long)m;
|
||||
}
|
||||
chunk_voxel_pos inline modulo(const voxel_pos& value, const chunk_voxel_pos& m) {
|
||||
return chunk_voxel_pos(rem(value.x, m.x), rem(value.y, m.y), rem(value.z, m.z));
|
||||
}
|
||||
chunk_pos inline divide(const voxel_pos &value, const chunk_voxel_pos &m)
|
||||
{
|
||||
return chunk_pos(div(value.x, m.x), div(value.y, m.y), div(value.z, m.z));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "glm.hpp"
|
||||
#include <glm/gtx/hash.hpp>
|
||||
|
||||
namespace glm {
|
||||
constexpr ivec3 inline iround(const vec3& p) {
|
||||
return ivec3(std::round<int>(p.x), std::round<int>(p.y), std::round<int>(p.z));
|
||||
}
|
||||
constexpr int inline length2(const ivec3& a) {
|
||||
return a.x * a.x + a.y * a.y + a.z * a.z;
|
||||
}
|
||||
constexpr ivec3 inline diff(const ivec3& a, const ivec3& b) {
|
||||
return glm::abs(glm::abs(a) - glm::abs(b));
|
||||
}
|
||||
|
||||
constexpr uint inline rem(long long value, uint m) {
|
||||
return value < 0 ? ((value+1) % (long long)m) + m - 1 : value % (long long)m;
|
||||
}
|
||||
constexpr int inline div(long long value, uint m) {
|
||||
return value < 0 ? ((value+1) / (long long)m) - 1 : value / (long long)m;
|
||||
}
|
||||
constexpr ucvec3 inline modulo(const lvec3& value, const ucvec3& m) {
|
||||
return ucvec3(rem(value.x, m.x), rem(value.y, m.y), rem(value.z, m.z));
|
||||
}
|
||||
constexpr ivec3 inline divide(const lvec3 &value, const ucvec3 &m) {
|
||||
return ivec3(div(value.x, m.x), div(value.y, m.y), div(value.z, m.z));
|
||||
}
|
||||
constexpr std::pair<ivec3, ucvec3> inline split(const lvec3 &value, const ucvec3 &m) {
|
||||
return {divide(value, m), modulo(value, m)};
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ namespace data {
|
|||
public:
|
||||
void push(const K& key, const V& val, const W& weight) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
heap.push_back({key, weight});
|
||||
heap.emplace_back(key, weight);
|
||||
std::push_heap(heap.begin(), heap.end(), cmpByWeight);
|
||||
map.insert_or_assign(key, val);
|
||||
cv.notify_one();
|
||||
|
@ -87,7 +87,7 @@ namespace data {
|
|||
public:
|
||||
void push(const K& key, const W& weight) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
heap.push_back({key, weight});
|
||||
heap.emplace_back(key, weight);
|
||||
std::push_heap(heap.begin(), heap.end(), cmpByWeight);
|
||||
set.insert(key);
|
||||
cv.notify_one();
|
||||
|
|
|
@ -21,6 +21,13 @@ namespace data {
|
|||
cv.notify_one();
|
||||
}
|
||||
|
||||
template <typename... _Args>
|
||||
void emplace(_Args &&... __args) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
queue.emplace(std::forward<_Args>(__args)...);
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
bool pop(T& out) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
if (queue.empty())
|
||||
|
|
|
@ -7,22 +7,18 @@
|
|||
* Univerxel main program.
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "render/window.hpp"
|
||||
#include "render/UI.hpp"
|
||||
#include "control/InputMap.hpp"
|
||||
#include "control/Camera.hpp"
|
||||
#include "control/InputMap.hpp" //TODO: add options
|
||||
|
||||
#include "render/Renderer.hpp"
|
||||
#include "render/pass/ColorProgram.hpp"
|
||||
#include "render/buffer/Colored.hpp"
|
||||
#include "world/Universe.hpp"
|
||||
|
||||
#include "state.h"
|
||||
#include "data/math.hpp"
|
||||
|
||||
#include <Remotery.h>
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ void Renderer::unloadTextures() {
|
|||
void Renderer::loadTextures(const std::string& texturePath, float mipMapLOD) {
|
||||
std::vector<std::string> terrainTextures;
|
||||
for(const auto texture: world::materials::textures) {
|
||||
terrainTextures.push_back(texturePath + "/terrain/" + texture);
|
||||
terrainTextures.emplace_back(texturePath + "/terrain/" + texture);
|
||||
}
|
||||
TextureAtlas = pass::Program::loadTextureArray(terrainTextures, "", mipMapLOD);
|
||||
NormalAtlas = pass::Program::loadTextureArray(terrainTextures, ".nrm", mipMapLOD);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <imgui.h>
|
||||
#include "pass/Context.hpp"
|
||||
#include "pass/MainProgram.hpp"
|
||||
#include "pass/SkyProgram.hpp"
|
||||
#include "pass/Context.hpp"
|
||||
|
||||
class Camera;
|
||||
/// Handle rendering passes and params
|
||||
|
@ -23,7 +22,7 @@ public:
|
|||
/// Textures quality
|
||||
float mipMapLOD = -.5;
|
||||
/// Depth color
|
||||
ImVec4 clear_color;
|
||||
glm::vec4 clear_color;
|
||||
};
|
||||
|
||||
Renderer(const options&);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "UI.hpp"
|
||||
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "pass/Program.hpp"
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include "../state.h"
|
||||
#include "../contouring/Abstract.hpp"
|
||||
#include "../world/materials.hpp"
|
||||
|
||||
|
@ -88,7 +89,7 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
actions = actions | Actions::RendererSharders;
|
||||
}
|
||||
}
|
||||
if (ImGui::ColorEdit3("Fog color", (float *)&options.renderer.clear_color)) {
|
||||
if (ImGui::ColorEdit3("Fog color", &options.renderer.clear_color[0])) {
|
||||
actions = actions | Actions::ClearColor;
|
||||
}
|
||||
if (ImGui::Checkbox("Wireframe", &options.renderer.wireframe))
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "../state.h"
|
||||
|
||||
class options;
|
||||
class state;
|
||||
class reports;
|
||||
namespace UI {
|
||||
/// Retro actions to state
|
||||
enum class Actions {
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
namespace buffer {
|
||||
/// Vertex properties
|
||||
struct VertexData {
|
||||
VertexData(const glm::vec3 &position, GLushort material, const glm::vec3 &normal):
|
||||
Position(position), Material(material), Normal(normal) { }
|
||||
glm::vec3 Position;
|
||||
GLushort Material;
|
||||
glm::vec3 Normal;
|
||||
|
|
|
@ -8,13 +8,13 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
|
||||
std::vector<std::string> flags;
|
||||
if(opts.pbr)
|
||||
flags.push_back("PBR");
|
||||
flags.emplace_back("PBR");
|
||||
if(opts.triplanar)
|
||||
flags.push_back("TRIPLANAR");
|
||||
flags.emplace_back("TRIPLANAR");
|
||||
if (opts.fog)
|
||||
flags.push_back("FOG");
|
||||
flags.emplace_back("FOG");
|
||||
if (opts.blend)
|
||||
flags.push_back("BLEND");
|
||||
flags.emplace_back("BLEND");
|
||||
|
||||
std::vector<Shader*> shaders;
|
||||
shaders.push_back(loadShader(GL_VERTEX_SHADER, flags));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "Shader.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
#include "control/Camera.hpp"
|
||||
#include "contouring/index.hpp"
|
||||
|
||||
inline ImColor fromHex(const std::string& str) {
|
||||
inline glm::vec4 fromHex(const std::string& str) {
|
||||
int rgb[3] = {UCHAR_MAX};
|
||||
sscanf(str.c_str() + 1, "%02X%02X%02X", (unsigned int *)&rgb[0], (unsigned int *)&rgb[1], (unsigned int *)&rgb[2]);
|
||||
return ImColor(rgb[0], rgb[1], rgb[2]);
|
||||
return glm::vec4(rgb[0] * 1.f / UCHAR_MAX, rgb[1] * 1.f / UCHAR_MAX, rgb[2] * 1.f / UCHAR_MAX, 1);
|
||||
}
|
||||
inline std::string toHexa(const ImVec4& rgba) {
|
||||
inline std::string toHexa(const glm::vec4& rgb) {
|
||||
auto out = (char*)malloc(8 * sizeof(char));
|
||||
sprintf(out, "#%02X%02X%02X", (int)(rgba.x * UCHAR_MAX), (int)(rgba.y * UCHAR_MAX), (int)(rgba.z * UCHAR_MAX));
|
||||
sprintf(out, "#%02X%02X%02X", (int)(rgb.x * UCHAR_MAX), (int)(rgb.y * UCHAR_MAX), (int)(rgb.z * UCHAR_MAX));
|
||||
return std::string(out);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "Chunk.hpp"
|
||||
|
||||
#include <FastNoiseSIMD.h>
|
||||
#include "materials.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace world;
|
||||
|
||||
|
@ -35,7 +35,7 @@ Chunk::Chunk(std::istream& str) {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
assert(i == CHUNK_SIZE-1);
|
||||
assert(("Mismatch data length", i == CHUNK_SIZE-1));
|
||||
#else
|
||||
for(auto& voxel: voxels) {
|
||||
str.read(reinterpret_cast<char *>(&voxel.Density), sizeof(Voxel::Density));
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <sstream>
|
||||
|
||||
/// Chunk length
|
||||
#define CHUNK_LENGTH 32
|
||||
#define CHUNK_LENGTH2 (CHUNK_LENGTH * CHUNK_LENGTH)
|
||||
#define CHUNK_SIZE (CHUNK_LENGTH2 * CHUNK_LENGTH)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <FastNoiseSIMD.h>
|
||||
#include <tuple>
|
||||
#include "../data/glm.hpp"
|
||||
#include "position.h"
|
||||
|
||||
namespace world {
|
||||
/// Noise generator
|
||||
|
|
|
@ -63,7 +63,7 @@ void Region::load() {
|
|||
const auto saved = content.insert({pos, data}).second;
|
||||
#endif
|
||||
if(!saved) {
|
||||
std::cout << "Duplicated chunk: " << path << ":" << pos.x << "." << pos.y << "." << pos.z << std::endl;
|
||||
std::cout << "Duplicated chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << std::endl;
|
||||
}
|
||||
file.peek();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void Region::load() {
|
|||
file.close();
|
||||
#endif
|
||||
}
|
||||
bool Region::read(const region_chunk_pos& pos, ZSTD_DCtx* dctx, data& out) {
|
||||
bool Region::read(const region_chunk_pos& pos, ZSTD_DCtx* ctx, ZSTD_DDict *dict, data& out) {
|
||||
#ifdef LOW_MEMORY
|
||||
std::unique_lock lock(mutex);
|
||||
|
||||
|
@ -102,22 +102,24 @@ bool Region::read(const region_chunk_pos& pos, ZSTD_DCtx* dctx, data& out) {
|
|||
|
||||
const auto maxSize = ZSTD_getFrameContentSize(in->data(), in->size());
|
||||
out.resize(maxSize);
|
||||
const auto actualSize = ZSTD_decompressDCtx(dctx, out.data(), out.size(), in->data(), in->size());
|
||||
const auto actualSize = ZSTD_decompress_usingDDict(ctx, out.data(), out.size(), in->data(), in->size(), dict);
|
||||
if(ZSTD_isError(actualSize)) {
|
||||
std::cout << "Corrupted region chunk: " << path << ":" << pos.x << "." << pos.y << "." << pos.z << std::endl;
|
||||
std::cout << "Corrupted region chunk: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
|
||||
<< ZSTD_getErrorName(actualSize) << std::endl;
|
||||
return false;
|
||||
}
|
||||
out.resize(actualSize);
|
||||
return true;
|
||||
}
|
||||
void Region::save(const region_chunk_pos& pos, ZSTD_CCtx* cctx, const std::string_view& in) {
|
||||
void Region::save(const region_chunk_pos& pos, ZSTD_CCtx* ctx, ZSTD_CDict* dict, const std::string_view& in) {
|
||||
const auto maxSize = ZSTD_compressBound(in.size());
|
||||
const auto buffer = new Region::data();
|
||||
buffer->resize(maxSize);
|
||||
|
||||
const auto actualSize = ZSTD_compressCCtx(cctx, buffer->data(), buffer->capacity(), in.data(), in.size(), ZSTD_CLEVEL_DEFAULT);
|
||||
const auto actualSize = ZSTD_compress_usingCDict(ctx, buffer->data(), buffer->capacity(), in.data(), in.size(), dict);
|
||||
if (ZSTD_isError(actualSize)) {
|
||||
std::cout << "Corrupted chunk save: " << path << ":" << pos.x << "." << pos.y << "." << pos.z << std::endl;
|
||||
std::cout << "Corrupted chunk save: " << path << ":" << (int)pos.x << "." << (int)pos.y << "." << (int)pos.z << " "
|
||||
<< ZSTD_getErrorName(actualSize) << std::endl;
|
||||
return;
|
||||
}
|
||||
buffer->resize(actualSize);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "../data/glm.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include <zstd.h>
|
||||
#include <robin_hood.h>
|
||||
#include <fstream>
|
||||
#include <zstd.h>
|
||||
#include "forward.h"
|
||||
#include "../data/math.hpp"
|
||||
|
||||
#define REGION_LENGTH 32
|
||||
namespace world {
|
||||
///Group of chunks saved as a single file
|
||||
class Region {
|
||||
|
@ -17,8 +17,8 @@ namespace world {
|
|||
|
||||
typedef std::vector<char> data;
|
||||
|
||||
bool read(const region_chunk_pos &pos, ZSTD_DCtx *dctx, data &out);
|
||||
void save(const region_chunk_pos &pos, ZSTD_CCtx *cctx, const std::string_view &in);
|
||||
bool read(const region_chunk_pos &pos, ZSTD_DCtx *dctx, ZSTD_DDict *ddict, data &out);
|
||||
void save(const region_chunk_pos &pos, ZSTD_CCtx *cctx, ZSTD_CDict *cdict, const std::string_view &in);
|
||||
|
||||
private:
|
||||
std::string path;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#include "Universe.hpp"
|
||||
|
||||
#include "../contouring/Dummy.hpp"
|
||||
#include "../data/geometry/Sphere.hpp"
|
||||
#include <Remotery.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <zstd.h>
|
||||
|
||||
#include "../contouring/Dummy.hpp"
|
||||
#include "Chunk.hpp"
|
||||
|
||||
using namespace world;
|
||||
|
||||
|
@ -20,9 +19,24 @@ Universe::Universe(const Universe::options &options): generator(42), contouring(
|
|||
running = true;
|
||||
std::filesystem::create_directories(folderPath);
|
||||
|
||||
{ // Load dictionary
|
||||
std::ifstream is("content/zstd.dict", std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if(!is.good()) {
|
||||
std::cout << "missing dict" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
const auto end = is.tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
std::vector<char> dict(end - is.tellg());
|
||||
is.read(dict.data(), dict.size());
|
||||
is.close();
|
||||
cdict = ZSTD_createCDict(dict.data(), dict.size(), ZSTD_CLEVEL_DEFAULT);
|
||||
ddict = ZSTD_createDDict(dict.data(), dict.size());
|
||||
}
|
||||
|
||||
// Load workers
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
loadWorkers.push_back(std::thread([&] {
|
||||
loadWorkers.emplace_back([&] {
|
||||
ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
||||
while (running) {
|
||||
chunk_pos ctx;
|
||||
|
@ -34,7 +48,7 @@ Universe::Universe(const Universe::options &options): generator(42), contouring(
|
|||
const region_chunk_pos cPos = glm::modulo(ctx, region_chunk_pos(REGION_LENGTH));
|
||||
const auto reg = getRegion(rPos);
|
||||
Region::data data;
|
||||
if(reg->read(cPos, dctx, data)) {
|
||||
if(reg->read(cPos, dctx, ddict, data)) {
|
||||
rmt_ScopedCPUSample(ProcessRead, 0);
|
||||
vec_istream idata(data);
|
||||
std::istream iss(&idata);
|
||||
|
@ -46,12 +60,12 @@ Universe::Universe(const Universe::options &options): generator(42), contouring(
|
|||
}
|
||||
}
|
||||
ZSTD_freeDCtx(dctx);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// Save workers
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
saveWorkers.push_back(std::thread([&] {
|
||||
saveWorkers.emplace_back([&] {
|
||||
ZSTD_CCtx* cctx = ZSTD_createCCtx();
|
||||
while (running) {
|
||||
robin_hood::pair<chunk_pos, std::shared_ptr<Chunk>> ctx;
|
||||
|
@ -64,11 +78,11 @@ Universe::Universe(const Universe::options &options): generator(42), contouring(
|
|||
const region_pos rPos = glm::divide(ctx.first, region_chunk_pos(REGION_LENGTH));
|
||||
const region_chunk_pos cPos = glm::modulo(ctx.first, region_chunk_pos(REGION_LENGTH));
|
||||
const auto reg = getRegion(rPos);
|
||||
reg->save(cPos, cctx, out.str());
|
||||
reg->save(cPos, cctx, cdict, out.str());
|
||||
}
|
||||
}
|
||||
ZSTD_freeCCtx(cctx);
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
Universe::~Universe() {
|
||||
|
@ -97,6 +111,9 @@ Universe::~Universe() {
|
|||
if (worker.joinable())
|
||||
worker.join();
|
||||
}
|
||||
|
||||
ZSTD_freeCDict(cdict);
|
||||
ZSTD_freeDDict(ddict);
|
||||
}
|
||||
|
||||
std::shared_ptr<Region> Universe::getRegion(const region_pos& pos) {
|
||||
|
@ -171,6 +188,7 @@ void Universe::update(const camera_pos& pos, Universe::report& rep) {
|
|||
}
|
||||
}
|
||||
rep.chunk_count.push(chunks.size());
|
||||
rep.region_count.push(regionCache.size());
|
||||
}
|
||||
void Universe::setOptions(const Universe::options& options) {
|
||||
loadDistance = options.loadDistance;
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include "../data/math.hpp"
|
||||
#include "../data/safe_queue.hpp"
|
||||
#include "../data/safe_priority_queue.hpp"
|
||||
#include "../data/circular_buffer.hpp"
|
||||
#include "Chunk.hpp"
|
||||
#include "Region.hpp"
|
||||
#include "../data/geometry/Ray.hpp"
|
||||
#include <shared_mutex>
|
||||
#include "forward.h"
|
||||
#include "Voxel.hpp"
|
||||
#include "Region.hpp"
|
||||
#include "Generator.hpp"
|
||||
typedef glm::vec3 camera_pos;
|
||||
|
||||
#define REPORT_BUFFER_SIZE 128
|
||||
|
||||
|
@ -40,9 +44,11 @@ namespace world {
|
|||
circular_buffer<float> chunk_load = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
|
||||
/// Saved chunks
|
||||
circular_buffer<float> chunk_unload = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
|
||||
/// Regions in memory
|
||||
circular_buffer<float> region_count = circular_buffer<float>(REPORT_BUFFER_SIZE, 0);
|
||||
};
|
||||
|
||||
Universe(const options&);
|
||||
Universe(const options &);
|
||||
~Universe();
|
||||
|
||||
/// Update physics and contouring
|
||||
|
@ -69,7 +75,7 @@ namespace world {
|
|||
chunk_pos last_pos = chunk_pos(INT_MAX);
|
||||
|
||||
/// Data
|
||||
robin_hood::unordered_map<chunk_pos, std::shared_ptr<Chunk>> chunks;
|
||||
chunk_map chunks;
|
||||
|
||||
std::optional<std::shared_ptr<Chunk>> at(const chunk_pos& pos) const {
|
||||
const auto it = chunks.find(pos);
|
||||
|
@ -94,6 +100,8 @@ namespace world {
|
|||
|
||||
std::shared_mutex regionMutex; //MAYBE: shared_guard
|
||||
robin_hood::unordered_map<region_pos, std::shared_ptr<Region>> regionCache;
|
||||
ZSTD_CDict *cdict;
|
||||
ZSTD_DDict *ddict;
|
||||
//TODO: region pick list
|
||||
std::shared_ptr<Region> getRegion(const region_pos &);
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <robin_hood.h>
|
||||
#include "position.h"
|
||||
|
||||
namespace world {
|
||||
class Chunk;
|
||||
class Region;
|
||||
typedef robin_hood::unordered_map<chunk_pos, std::shared_ptr<Chunk>> chunk_map;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "../data/glm.hpp"
|
||||
|
||||
#define CHUNK_LENGTH 32
|
||||
#define REGION_LENGTH 32
|
||||
|
||||
typedef glm::lvec3 voxel_pos;
|
||||
typedef glm::ivec3 chunk_pos;
|
||||
typedef glm::ucvec3 chunk_voxel_pos;
|
||||
typedef glm::ivec3 region_pos;
|
||||
typedef glm::ucvec3 region_chunk_pos;
|
Loading…
Reference in New Issue