Commit 752cd4b1 authored by Shu's avatar Shu 🍠
Browse files

Zstd dictionary, forward decl

parent 8d967cee
......@@ -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."
)
\ No newline at end of file
)
# 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")
\ No newline at end of file
......@@ -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
......
/**
* \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;
}
\ No newline at end of file
#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
......
#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);
}
}
}
\ No newline at end of file
#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)]);
}
}
......
#pragma once
#include "Abstract.hpp"
#include <map>
namespace contouring {
static const std::array<std::string, 3> names = {"FlatDualMC", "FlatBox", "Dummy"};
......
#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())
......
#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);
}}
}
}
......
#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));
}
}
#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)};
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment