Commit 7d125b81 authored by Shu's avatar Shu 🍠
Browse files

Push It To The Limit + HastyNoise

parent 6ace01af
......@@ -10,7 +10,7 @@
"label": "cmake",
"type": "shell",
"command": "cmake",
"args": [".."],
"args": ["-DFIXED_WINDOW=1", ".."],
"options": {
"cwd": "${workspaceRoot}/build"
}
......@@ -19,7 +19,7 @@
"label": "cmake info",
"type": "shell",
"command": "cmake",
"args": ["-DCMAKE_BUILD_TYPE=RelWithDebInfo", ".."],
"args": ["-DFIXED_WINDOW=1", "-DCMAKE_BUILD_TYPE=RelWithDebInfo", ".."],
"options": {
"cwd": "${workspaceRoot}/build"
}
......@@ -28,7 +28,7 @@
"label": "cmake debug",
"type": "shell",
"command": "cmake",
"args": ["-DCMAKE_BUILD_TYPE=Debug", ".."],
"args": ["-DFIXED_WINDOW=1", "-DCMAKE_BUILD_TYPE=Debug", ".."],
"options": {
"cwd": "${workspaceRoot}/build"
}
......
......@@ -4,7 +4,8 @@ project (univerxel VERSION 0.0.1)
cmake_policy(SET CMP0072 NEW)
find_package(OpenGL REQUIRED)
option(PROFILING "Build with profiling" OFF)
option(PROFILING "Build with profiling" 0)
option(FIXED_WINDOW "Lock window size: Force floating on i3" 0)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
......@@ -52,12 +53,7 @@ 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})
if(PROFILING)
target_compile_definitions(univerxel PRIVATE RMT_ENABLED=1 RMT_USE_OPENGL=1)
else(PROFILING)
target_compile_definitions(univerxel PRIVATE RMT_ENABLED=0)
endif(PROFILING)
add_dependencies(univerxel generate_dictionary)
target_compile_definitions(univerxel PRIVATE RMT_ENABLED=${PROFILING} RMT_USE_OPENGL=${PROFILING} FIXED_WINDOW=${FIXED_WINDOW} HN_USE_FILESYSTEM=1)
file(COPY content/shaders DESTINATION ${CMAKE_BINARY_DIR}/content)
file(COPY content/textures DESTINATION ${CMAKE_BINARY_DIR}/content)
......@@ -70,14 +66,13 @@ add_custom_target(docs
)
# 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")
file(GLOB SMP_SOURCES "src/zstd_sampler.cpp" "src/world/Chunk.cpp" "include/FastNoiseSIMD/*.cpp")
add_executable(zstd_sampler EXCLUDE_FROM_ALL ${SMP_SOURCES})
target_compile_features(zstd_sampler PUBLIC cxx_std_17)
target_link_libraries(zstd_sampler ${LINKED_LIBS})
target_include_directories(zstd_sampler PRIVATE "include/FastNoiseSIMD")
# target_compile_definitions(zstd_sampler PRIVATE HN_USE_FILESYSTEM=1)
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)
COMMAND "${CMAKE_BINARY_DIR}/zstd_sampler" DEPENDS zstd_sampler)
add_custom_target(generate_dictionary DEPENDS "${CMAKE_BINARY_DIR}/content/zstd.dict")
\ No newline at end of file
......@@ -35,6 +35,7 @@
- [ ] Server
- [ ] ZeroMQ
- [x] Logger
- [ ] FastNoiseSIMD / HastyNoise double precision
## Rendering
- [x] Render triangle
......@@ -56,6 +57,7 @@
- [ ] Deferred
- [ ] Cascaded shadow maps
- [ ] RayCast
- [x] Float precision problem
## Contouring
- [x] Box contouring
......
/**
* \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 <ctime>
#include <filesystem>
#include <fstream>
#include <iostream>
const auto SAMPLE_SIZE = 10000;
/// Entry point
int main(int /*unused*/, char * /*unused*/[])
{
std::srand(std::time(nullptr));
world::Generator generator(std::rand());
std::filesystem::create_directories("samples");
for (size_t i = 0; i < SAMPLE_SIZE; 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
......@@ -4,7 +4,6 @@
#include "../data/geometry/Frustum.hpp"
#include "../data/geometry/Faces.hpp"
#include "../world/forward.h"
typedef glm::vec3 camera_pos;
/// Mesh creation
namespace contouring {
......@@ -16,10 +15,10 @@ namespace contouring {
/// Each frame ping.
/// Mostly used for cleanup and to flush buffers data using main thread
virtual void update(const camera_pos &pos) = 0;
virtual void update(const voxel_pos &pos) = 0;
/// Chunk data change
virtual void onUpdate(const chunk_pos &pos, const world::chunk_map& 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 world::chunk_map &data) = 0;
......@@ -30,6 +29,6 @@ namespace contouring {
/// Get buffers in frustum with model matrices
/// @note buffers invalidated after update
virtual void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &buffers, const std::optional<geometry::Frustum>& frustum, float scale) = 0;
virtual void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &buffers, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density) = 0;
};
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
#include "../world/Chunk.hpp"
namespace contouring {
void AbstractFlat::update(const camera_pos& pos) {
void AbstractFlat::update(const voxel_pos& pos) {
center = glm::divide(pos, chunk_voxel_pos(CHUNK_LENGTH));
auto it = buffers.begin();
while (it != buffers.end()) { // Remove out of range buffers
......@@ -39,11 +39,12 @@ namespace contouring {
ImGui::SliderInt("Keep Distance", &keepDistance, loadDistance+1, 21);
}
void AbstractFlat::getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &out, const std::optional<geometry::Frustum> &frustum, float scale) {
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(scale));
void AbstractFlat::getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density) {
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
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.emplace_back(glm::translate(scaling, glm::vec3(pos) * glm::vec3(CHUNK_LENGTH)), buffer);
const glm::vec3 fPos = glm::vec3(glm::llvec3(pos) * glm::llvec3(CHUNK_LENGTH) - offset * glm::llvec3(density)) / glm::vec3(density);
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(fPos, glm::vec3(CHUNK_LENGTH / (float)density)))))
out.emplace_back(glm::translate(scaling, fPos * (float)density), buffer);
}
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ namespace contouring {
virtual ~AbstractFlat() {}
/// Each frame ping. Used to clear out of range
void update(const camera_pos &) override;
void update(const voxel_pos &) override;
/// Display ImGui config
void onGui() override;
......@@ -20,7 +20,7 @@ namespace contouring {
/// Get buffers in frustum with model matrices
/// @note buffers invalidated after update
void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &out, const std::optional<geometry::Frustum> &frustum, float scale) override;
void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density) override;
protected:
bool inline inLoadRange(const chunk_pos& point) const {
......
......@@ -9,11 +9,11 @@ namespace contouring {
Dummy(): Abstract() { }
virtual ~Dummy() { }
void update(const camera_pos &) override { }
void update(const voxel_pos &) 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 { }
void getModels(std::vector<std::pair<glm::mat4, buffer::Abstract *const>> &, const std::optional<geometry::Frustum>&, const glm::llvec3&, int) override { }
};
}
\ No newline at end of file
......@@ -75,7 +75,7 @@ namespace contouring {
}
}
void FlatDualMC::update(const camera_pos& pos) {
void FlatDualMC::update(const voxel_pos& pos) {
AbstractFlat::update(pos);
std::pair<chunk_pos, buffer::ShortIndexed::Data> out;
reports.load.push(loadQueue.size());
......
......@@ -19,7 +19,7 @@ namespace contouring {
FlatDualMC(const std::string&);
virtual ~FlatDualMC();
void update(const camera_pos&) override;
void update(const voxel_pos&) override;
void onGui() override;
......
......@@ -74,7 +74,7 @@ namespace contouring {
}
}
void FlatSurroundingBox::update(const camera_pos& pos) {
void FlatSurroundingBox::update(const voxel_pos& pos) {
AbstractFlat::update(pos);
std::pair<chunk_pos, buffer::ShortIndexed::Data> out;
reports.load.push(loadQueue.size());
......
......@@ -19,7 +19,7 @@ namespace contouring {
FlatSurroundingBox(const std::string&);
virtual ~FlatSurroundingBox();
void update(const camera_pos&) override;
void update(const voxel_pos&) override;
void onGui() override;
......
......@@ -15,15 +15,15 @@ namespace contouring::surrounding {
std::pair<ushort, ushort> getNeighborIdx(ushort idx, geometry::Face face);
typedef std::array<std::shared_ptr<const world::Chunk>, 8> corners;
const glm::ivec3 g_corner_offsets[8] = {
glm::ivec3(0, 0, 0),
glm::ivec3(0, 0, 1),
glm::ivec3(0, 1, 0),
glm::ivec3(0, 1, 1),
glm::ivec3(1, 0, 0),
glm::ivec3(1, 0, 1),
glm::ivec3(1, 1, 0),
glm::ivec3(1, 1, 1),
const chunk_pos g_corner_offsets[8] = {
chunk_pos(0, 0, 0),
chunk_pos(0, 0, 1),
chunk_pos(0, 1, 0),
chunk_pos(0, 1, 1),
chunk_pos(1, 0, 0),
chunk_pos(1, 0, 1),
chunk_pos(1, 1, 0),
chunk_pos(1, 1, 1),
};
bool load(corners &out, const chunk_pos &chunkPos, const world::chunk_map &chunks);
......
......@@ -3,7 +3,8 @@
#include <glm/gtc/matrix_transform.hpp>
#include "../render/window.hpp"
Camera::Camera(GLFWwindow *window, const InputMap& inputs, const Camera::options& opt): window(window), inputs(inputs), o(opt) {
Camera::Camera(GLFWwindow *window, const InputMap& inputs, const Camera::options& opt): window(window), inputs(inputs),
Position(voxel_pos(1ll << 24), 1), o(opt){
updateProjection();
}
Camera::~Camera() { }
......@@ -57,36 +58,37 @@ void Camera::update(bool captureMouse, bool captureKeys) {
if(captureKeys) {
// Move forward
if (inputs.isDown(Input::Forward)) {
Position += direction * deltaTime * o.speed;
Position.offset += direction * deltaTime * o.speed;
}
// Move backward
if (inputs.isDown(Input::Backward)) {
Position -= direction * deltaTime * o.speed;
Position.offset -= direction * deltaTime * o.speed;
}
// Strafe right
if (inputs.isDown(Input::Right)) {
Position += right * deltaTime * o.speed;
Position.offset += right * deltaTime * o.speed;
}
// Strafe left
if (inputs.isDown(Input::Left)) {
Position -= right * deltaTime * o.speed;
Position.offset -= right * deltaTime * o.speed;
}
// Move up
if (inputs.isDown(Input::Up)) {
Position += up * deltaTime * o.speed;
Position.offset += up * deltaTime * o.speed;
}
// Move down
if (inputs.isDown(Input::Down)) {
Position -= up * deltaTime * o.speed;
Position.offset -= up * deltaTime * o.speed;
}
Position.center();
}
// MAYBE: only if moved
// MAYBE: save frustum
// Camera matrix
ViewMatrix = glm::lookAt(
Position, // Camera is here
Position + direction, // and looks here : at the same position, plus "direction"
Position.offset, // Camera is here
Position.offset + direction, // and looks here : at the same position, plus "direction"
up // Head is up (set to 0,-1,0 to look upside-down)
);
......
......@@ -7,7 +7,7 @@
#include "../data/glm.hpp"
#include "../data/geometry/Frustum.hpp"
#include "../data/geometry/Ray.hpp"
typedef glm::vec3 camera_pos;
#include "../world/position.h"
/// Moving perspective camera
class Camera {
......@@ -36,7 +36,7 @@ public:
constexpr glm::mat4 getViewMatrix() const { return ViewMatrix; }
constexpr glm::mat4 getProjectionMatrix() const { return ProjectionMatrix; }
constexpr camera_pos getPosition() const { return Position; }
camera_pos getPosition() const { return Position; }
constexpr float getDepth() const { return o.far; }
private:
......@@ -47,7 +47,7 @@ private:
glm::mat4 ProjectionMatrix;
void updateProjection();
camera_pos Position = glm::vec3(0, 0, 5);
camera_pos Position;
float HorizontalAngle = 3.14f;
float VerticalAngle = 0.0f;
......
#pragma once
#include "../glm.hpp"
#include "../../world/position.h"
/// Math utils
namespace geometry {
enum class Face {
Right, Left, Up, Down, Forward, Backward
};
const glm::ivec3 g_face_offsets[6] = {
glm::ivec3(1,0,0), glm::ivec3(-1,0,0),
glm::ivec3(0,1,0), glm::ivec3(0,-1,0),
glm::ivec3(0,0,1), glm::ivec3(0,0,-1),
const chunk_pos g_face_offsets[6] = {
chunk_pos(1,0,0), chunk_pos(-1,0,0),
chunk_pos(0,1,0), chunk_pos(0,-1,0),
chunk_pos(0,0,1), chunk_pos(0,0,-1),
};
enum class Faces {
......
#pragma once
#include "Box.hpp"
#include "../glm.hpp"
#include "../../world/position.h"
namespace geometry {
/// Raycast with distance
struct Ray {
glm::vec3 from;
camera_pos from;
glm::vec3 dir;
float dist;
// MAYBE: Ray(const glm::mat4& view_matrix) { }
Ray(const glm::vec3& from, const glm::vec3& dir, float dist): from(from), dir(glm::normalize(dir)), dist(dist) { }
Ray(const camera_pos& from, const glm::vec3& dir, float dist): from(from), dir(glm::normalize(dir)), dist(dist) { }
inline Ray operator/(float scale) const noexcept {
return Ray(from / scale, dir, dist / scale);
inline Ray operator*(float scale) const noexcept {
return Ray(from * scale, dir, dist * scale);
}
/// Get path points in integer grid
/// @note not precise enough
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;
inline void grid(std::vector<glm::llvec3>& points) const {
glm::llvec3 current = from.as_voxel();
const glm::llvec3 d = dir * dist;
const glm::llvec3 inc = glm::llvec3((d.x < 0) ? -1 : 1, (d.y < 0) ? -1 : 1, (d.z < 0) ? -1 : 1);
const glm::llvec3 size = glm::abs(d);
const glm::llvec3 delta = size << 1ll;
if ((size.x >= size.y) && (size.x >= size.z)) {
int err_1 = delta.y - size.x;
......
......@@ -3,8 +3,8 @@
#include <glm/glm.hpp>
namespace glm {
typedef vec<3, long long> lvec3;
typedef vec<4, long long> lvec4;
typedef vec<3, long long> llvec3;
typedef vec<3, long> lvec3;
typedef vec<3, ushort> usvec3;
typedef vec<3, unsigned char> ucvec3;
}
......@@ -17,16 +17,19 @@ namespace glm {
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) {
constexpr long 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) {
constexpr ucvec3 inline modulo(const llvec3& 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 lvec3 inline divide(const llvec3 &value, const ucvec3 &m) {
return lvec3(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) {
constexpr lvec3 inline divide(const llvec3 &value, const uvec3 &m) {
return lvec3(div(value.x, m.x), div(value.y, m.y), div(value.z, m.z));
}
constexpr std::pair<lvec3, ucvec3> inline split(const llvec3 &value, const ucvec3 &m) {
return {divide(value, m), modulo(value, m)};
}
}
......@@ -97,14 +97,14 @@ int main(int /*unused*/, char */*unused*/[]){
renderer->lookFrom(camera);
state.position = camera.getPosition();
state.look_at = world.raycast(camera.getRay() / options.voxel_size);
state.look_at = world.raycast(camera.getRay() * options.voxel_density);
if (state.capture_mouse && state.look_at.has_value()) {
if (inputs.isPressing(Mouse::Left))
world.setCube(state.look_at.value().first, world::Voxel{0, 0}, options.tool.radius);
else if (inputs.isPressing(Mouse::Right))
world.setCube(state.look_at.value().first, world::Voxel{UCHAR_MAX, options.tool.material}, options.tool.radius);
}
world.update(state.position / options.voxel_size, reports.world);
world.update((state.position * options.voxel_density).as_voxel(), reports.world);
inputs.saveKeys();
reports.main.update.push((glfwGetTime() - partTime) * 1000);
}
......@@ -159,7 +159,8 @@ int main(int /*unused*/, char */*unused*/[]){
if(options.culling) {
frustum = {camera.getFrustum()};
}
world.getContouring()->getModels(models, frustum, options.voxel_size);
const auto offset = state.position.raw_as_long();
world.getContouring()->getModels(models, frustum, offset, options.voxel_density);
reports.main.models_count = 0;
reports.main.tris_count = 0;
rmt_ScopedOpenGLSample(Render);
......@@ -170,7 +171,7 @@ int main(int /*unused*/, char */*unused*/[]){
if(state.look_at.has_value()) {
lookProgram->useIt();
lookProgram->start(renderer);
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), glm::vec3(options.voxel_size)), glm::vec3(state.look_at.value().first) - glm::vec3(.5 + options.tool.radius)), glm::vec3(1 + options.tool.radius * 2));
const auto model = glm::scale(glm::translate(glm::scale(glm::mat4(1), 1.f / glm::vec3(options.voxel_density)), glm::vec3(state.look_at.value().first - offset * glm::llvec3(options.voxel_density)) - glm::vec3(.5 + options.tool.radius)), glm::vec3(1 + options.tool.radius * 2));
lookBuffer.draw(lookProgram->setup(renderer, model));
}
renderer->postProcess();
......
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